annotate src/libvorbis-1.3.3/lib/codebook.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 05aa0afa9217
children
rev   line source
Chris@1 1 /********************************************************************
Chris@1 2 * *
Chris@1 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
Chris@1 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
Chris@1 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Chris@1 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
Chris@1 7 * *
Chris@1 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
Chris@1 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
Chris@1 10 * *
Chris@1 11 ********************************************************************
Chris@1 12
Chris@1 13 function: basic codebook pack/unpack/code/decode operations
Chris@1 14 last mod: $Id: codebook.c 18183 2012-02-03 20:51:27Z xiphmont $
Chris@1 15
Chris@1 16 ********************************************************************/
Chris@1 17
Chris@1 18 #include <stdlib.h>
Chris@1 19 #include <string.h>
Chris@1 20 #include <math.h>
Chris@1 21 #include <ogg/ogg.h>
Chris@1 22 #include "vorbis/codec.h"
Chris@1 23 #include "codebook.h"
Chris@1 24 #include "scales.h"
Chris@1 25 #include "misc.h"
Chris@1 26 #include "os.h"
Chris@1 27
Chris@1 28 /* packs the given codebook into the bitstream **************************/
Chris@1 29
Chris@1 30 int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
Chris@1 31 long i,j;
Chris@1 32 int ordered=0;
Chris@1 33
Chris@1 34 /* first the basic parameters */
Chris@1 35 oggpack_write(opb,0x564342,24);
Chris@1 36 oggpack_write(opb,c->dim,16);
Chris@1 37 oggpack_write(opb,c->entries,24);
Chris@1 38
Chris@1 39 /* pack the codewords. There are two packings; length ordered and
Chris@1 40 length random. Decide between the two now. */
Chris@1 41
Chris@1 42 for(i=1;i<c->entries;i++)
Chris@1 43 if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
Chris@1 44 if(i==c->entries)ordered=1;
Chris@1 45
Chris@1 46 if(ordered){
Chris@1 47 /* length ordered. We only need to say how many codewords of
Chris@1 48 each length. The actual codewords are generated
Chris@1 49 deterministically */
Chris@1 50
Chris@1 51 long count=0;
Chris@1 52 oggpack_write(opb,1,1); /* ordered */
Chris@1 53 oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
Chris@1 54
Chris@1 55 for(i=1;i<c->entries;i++){
Chris@1 56 long this=c->lengthlist[i];
Chris@1 57 long last=c->lengthlist[i-1];
Chris@1 58 if(this>last){
Chris@1 59 for(j=last;j<this;j++){
Chris@1 60 oggpack_write(opb,i-count,_ilog(c->entries-count));
Chris@1 61 count=i;
Chris@1 62 }
Chris@1 63 }
Chris@1 64 }
Chris@1 65 oggpack_write(opb,i-count,_ilog(c->entries-count));
Chris@1 66
Chris@1 67 }else{
Chris@1 68 /* length random. Again, we don't code the codeword itself, just
Chris@1 69 the length. This time, though, we have to encode each length */
Chris@1 70 oggpack_write(opb,0,1); /* unordered */
Chris@1 71
Chris@1 72 /* algortihmic mapping has use for 'unused entries', which we tag
Chris@1 73 here. The algorithmic mapping happens as usual, but the unused
Chris@1 74 entry has no codeword. */
Chris@1 75 for(i=0;i<c->entries;i++)
Chris@1 76 if(c->lengthlist[i]==0)break;
Chris@1 77
Chris@1 78 if(i==c->entries){
Chris@1 79 oggpack_write(opb,0,1); /* no unused entries */
Chris@1 80 for(i=0;i<c->entries;i++)
Chris@1 81 oggpack_write(opb,c->lengthlist[i]-1,5);
Chris@1 82 }else{
Chris@1 83 oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
Chris@1 84 for(i=0;i<c->entries;i++){
Chris@1 85 if(c->lengthlist[i]==0){
Chris@1 86 oggpack_write(opb,0,1);
Chris@1 87 }else{
Chris@1 88 oggpack_write(opb,1,1);
Chris@1 89 oggpack_write(opb,c->lengthlist[i]-1,5);
Chris@1 90 }
Chris@1 91 }
Chris@1 92 }
Chris@1 93 }
Chris@1 94
Chris@1 95 /* is the entry number the desired return value, or do we have a
Chris@1 96 mapping? If we have a mapping, what type? */
Chris@1 97 oggpack_write(opb,c->maptype,4);
Chris@1 98 switch(c->maptype){
Chris@1 99 case 0:
Chris@1 100 /* no mapping */
Chris@1 101 break;
Chris@1 102 case 1:case 2:
Chris@1 103 /* implicitly populated value mapping */
Chris@1 104 /* explicitly populated value mapping */
Chris@1 105
Chris@1 106 if(!c->quantlist){
Chris@1 107 /* no quantlist? error */
Chris@1 108 return(-1);
Chris@1 109 }
Chris@1 110
Chris@1 111 /* values that define the dequantization */
Chris@1 112 oggpack_write(opb,c->q_min,32);
Chris@1 113 oggpack_write(opb,c->q_delta,32);
Chris@1 114 oggpack_write(opb,c->q_quant-1,4);
Chris@1 115 oggpack_write(opb,c->q_sequencep,1);
Chris@1 116
Chris@1 117 {
Chris@1 118 int quantvals;
Chris@1 119 switch(c->maptype){
Chris@1 120 case 1:
Chris@1 121 /* a single column of (c->entries/c->dim) quantized values for
Chris@1 122 building a full value list algorithmically (square lattice) */
Chris@1 123 quantvals=_book_maptype1_quantvals(c);
Chris@1 124 break;
Chris@1 125 case 2:
Chris@1 126 /* every value (c->entries*c->dim total) specified explicitly */
Chris@1 127 quantvals=c->entries*c->dim;
Chris@1 128 break;
Chris@1 129 default: /* NOT_REACHABLE */
Chris@1 130 quantvals=-1;
Chris@1 131 }
Chris@1 132
Chris@1 133 /* quantized values */
Chris@1 134 for(i=0;i<quantvals;i++)
Chris@1 135 oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
Chris@1 136
Chris@1 137 }
Chris@1 138 break;
Chris@1 139 default:
Chris@1 140 /* error case; we don't have any other map types now */
Chris@1 141 return(-1);
Chris@1 142 }
Chris@1 143
Chris@1 144 return(0);
Chris@1 145 }
Chris@1 146
Chris@1 147 /* unpacks a codebook from the packet buffer into the codebook struct,
Chris@1 148 readies the codebook auxiliary structures for decode *************/
Chris@1 149 static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
Chris@1 150 long i,j;
Chris@1 151 static_codebook *s=_ogg_calloc(1,sizeof(*s));
Chris@1 152 s->allocedp=1;
Chris@1 153
Chris@1 154 /* make sure alignment is correct */
Chris@1 155 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
Chris@1 156
Chris@1 157 /* first the basic parameters */
Chris@1 158 s->dim=oggpack_read(opb,16);
Chris@1 159 s->entries=oggpack_read(opb,24);
Chris@1 160 if(s->entries==-1)goto _eofout;
Chris@1 161
Chris@1 162 if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
Chris@1 163
Chris@1 164 /* codeword ordering.... length ordered or unordered? */
Chris@1 165 switch((int)oggpack_read(opb,1)){
Chris@1 166 case 0:{
Chris@1 167 long unused;
Chris@1 168 /* allocated but unused entries? */
Chris@1 169 unused=oggpack_read(opb,1);
Chris@1 170 if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
Chris@1 171 goto _eofout;
Chris@1 172 /* unordered */
Chris@1 173 s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
Chris@1 174
Chris@1 175 /* allocated but unused entries? */
Chris@1 176 if(unused){
Chris@1 177 /* yes, unused entries */
Chris@1 178
Chris@1 179 for(i=0;i<s->entries;i++){
Chris@1 180 if(oggpack_read(opb,1)){
Chris@1 181 long num=oggpack_read(opb,5);
Chris@1 182 if(num==-1)goto _eofout;
Chris@1 183 s->lengthlist[i]=num+1;
Chris@1 184 }else
Chris@1 185 s->lengthlist[i]=0;
Chris@1 186 }
Chris@1 187 }else{
Chris@1 188 /* all entries used; no tagging */
Chris@1 189 for(i=0;i<s->entries;i++){
Chris@1 190 long num=oggpack_read(opb,5);
Chris@1 191 if(num==-1)goto _eofout;
Chris@1 192 s->lengthlist[i]=num+1;
Chris@1 193 }
Chris@1 194 }
Chris@1 195
Chris@1 196 break;
Chris@1 197 }
Chris@1 198 case 1:
Chris@1 199 /* ordered */
Chris@1 200 {
Chris@1 201 long length=oggpack_read(opb,5)+1;
Chris@1 202 if(length==0)goto _eofout;
Chris@1 203 s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
Chris@1 204
Chris@1 205 for(i=0;i<s->entries;){
Chris@1 206 long num=oggpack_read(opb,_ilog(s->entries-i));
Chris@1 207 if(num==-1)goto _eofout;
Chris@1 208 if(length>32 || num>s->entries-i ||
Chris@1 209 (num>0 && (num-1)>>(length-1)>1)){
Chris@1 210 goto _errout;
Chris@1 211 }
Chris@1 212 if(length>32)goto _errout;
Chris@1 213 for(j=0;j<num;j++,i++)
Chris@1 214 s->lengthlist[i]=length;
Chris@1 215 length++;
Chris@1 216 }
Chris@1 217 }
Chris@1 218 break;
Chris@1 219 default:
Chris@1 220 /* EOF */
Chris@1 221 goto _eofout;
Chris@1 222 }
Chris@1 223
Chris@1 224 /* Do we have a mapping to unpack? */
Chris@1 225 switch((s->maptype=oggpack_read(opb,4))){
Chris@1 226 case 0:
Chris@1 227 /* no mapping */
Chris@1 228 break;
Chris@1 229 case 1: case 2:
Chris@1 230 /* implicitly populated value mapping */
Chris@1 231 /* explicitly populated value mapping */
Chris@1 232
Chris@1 233 s->q_min=oggpack_read(opb,32);
Chris@1 234 s->q_delta=oggpack_read(opb,32);
Chris@1 235 s->q_quant=oggpack_read(opb,4)+1;
Chris@1 236 s->q_sequencep=oggpack_read(opb,1);
Chris@1 237 if(s->q_sequencep==-1)goto _eofout;
Chris@1 238
Chris@1 239 {
Chris@1 240 int quantvals=0;
Chris@1 241 switch(s->maptype){
Chris@1 242 case 1:
Chris@1 243 quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
Chris@1 244 break;
Chris@1 245 case 2:
Chris@1 246 quantvals=s->entries*s->dim;
Chris@1 247 break;
Chris@1 248 }
Chris@1 249
Chris@1 250 /* quantized values */
Chris@1 251 if(((quantvals*s->q_quant+7)>>3)>opb->storage-oggpack_bytes(opb))
Chris@1 252 goto _eofout;
Chris@1 253 s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals);
Chris@1 254 for(i=0;i<quantvals;i++)
Chris@1 255 s->quantlist[i]=oggpack_read(opb,s->q_quant);
Chris@1 256
Chris@1 257 if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
Chris@1 258 }
Chris@1 259 break;
Chris@1 260 default:
Chris@1 261 goto _errout;
Chris@1 262 }
Chris@1 263
Chris@1 264 /* all set */
Chris@1 265 return(s);
Chris@1 266
Chris@1 267 _errout:
Chris@1 268 _eofout:
Chris@1 269 vorbis_staticbook_destroy(s);
Chris@1 270 return(NULL);
Chris@1 271 }
Chris@1 272
Chris@1 273 /* returns the number of bits ************************************************/
Chris@1 274 int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
Chris@1 275 if(a<0 || a>=book->c->entries)return(0);
Chris@1 276 oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
Chris@1 277 return(book->c->lengthlist[a]);
Chris@1 278 }
Chris@1 279
Chris@1 280 /* the 'eliminate the decode tree' optimization actually requires the
Chris@1 281 codewords to be MSb first, not LSb. This is an annoying inelegancy
Chris@1 282 (and one of the first places where carefully thought out design
Chris@1 283 turned out to be wrong; Vorbis II and future Ogg codecs should go
Chris@1 284 to an MSb bitpacker), but not actually the huge hit it appears to
Chris@1 285 be. The first-stage decode table catches most words so that
Chris@1 286 bitreverse is not in the main execution path. */
Chris@1 287
Chris@1 288 static ogg_uint32_t bitreverse(ogg_uint32_t x){
Chris@1 289 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
Chris@1 290 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
Chris@1 291 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
Chris@1 292 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
Chris@1 293 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
Chris@1 294 }
Chris@1 295
Chris@1 296 STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
Chris@1 297 int read=book->dec_maxlength;
Chris@1 298 long lo,hi;
Chris@1 299 long lok = oggpack_look(b,book->dec_firsttablen);
Chris@1 300
Chris@1 301 if (lok >= 0) {
Chris@1 302 long entry = book->dec_firsttable[lok];
Chris@1 303 if(entry&0x80000000UL){
Chris@1 304 lo=(entry>>15)&0x7fff;
Chris@1 305 hi=book->used_entries-(entry&0x7fff);
Chris@1 306 }else{
Chris@1 307 oggpack_adv(b, book->dec_codelengths[entry-1]);
Chris@1 308 return(entry-1);
Chris@1 309 }
Chris@1 310 }else{
Chris@1 311 lo=0;
Chris@1 312 hi=book->used_entries;
Chris@1 313 }
Chris@1 314
Chris@1 315 lok = oggpack_look(b, read);
Chris@1 316
Chris@1 317 while(lok<0 && read>1)
Chris@1 318 lok = oggpack_look(b, --read);
Chris@1 319 if(lok<0)return -1;
Chris@1 320
Chris@1 321 /* bisect search for the codeword in the ordered list */
Chris@1 322 {
Chris@1 323 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
Chris@1 324
Chris@1 325 while(hi-lo>1){
Chris@1 326 long p=(hi-lo)>>1;
Chris@1 327 long test=book->codelist[lo+p]>testword;
Chris@1 328 lo+=p&(test-1);
Chris@1 329 hi-=p&(-test);
Chris@1 330 }
Chris@1 331
Chris@1 332 if(book->dec_codelengths[lo]<=read){
Chris@1 333 oggpack_adv(b, book->dec_codelengths[lo]);
Chris@1 334 return(lo);
Chris@1 335 }
Chris@1 336 }
Chris@1 337
Chris@1 338 oggpack_adv(b, read);
Chris@1 339
Chris@1 340 return(-1);
Chris@1 341 }
Chris@1 342
Chris@1 343 /* Decode side is specced and easier, because we don't need to find
Chris@1 344 matches using different criteria; we simply read and map. There are
Chris@1 345 two things we need to do 'depending':
Chris@1 346
Chris@1 347 We may need to support interleave. We don't really, but it's
Chris@1 348 convenient to do it here rather than rebuild the vector later.
Chris@1 349
Chris@1 350 Cascades may be additive or multiplicitive; this is not inherent in
Chris@1 351 the codebook, but set in the code using the codebook. Like
Chris@1 352 interleaving, it's easiest to do it here.
Chris@1 353 addmul==0 -> declarative (set the value)
Chris@1 354 addmul==1 -> additive
Chris@1 355 addmul==2 -> multiplicitive */
Chris@1 356
Chris@1 357 /* returns the [original, not compacted] entry number or -1 on eof *********/
Chris@1 358 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
Chris@1 359 if(book->used_entries>0){
Chris@1 360 long packed_entry=decode_packed_entry_number(book,b);
Chris@1 361 if(packed_entry>=0)
Chris@1 362 return(book->dec_index[packed_entry]);
Chris@1 363 }
Chris@1 364
Chris@1 365 /* if there's no dec_index, the codebook unpacking isn't collapsed */
Chris@1 366 return(-1);
Chris@1 367 }
Chris@1 368
Chris@1 369 /* returns 0 on OK or -1 on eof *************************************/
Chris@1 370 /* decode vector / dim granularity gaurding is done in the upper layer */
Chris@1 371 long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){
Chris@1 372 if(book->used_entries>0){
Chris@1 373 int step=n/book->dim;
Chris@1 374 long *entry = alloca(sizeof(*entry)*step);
Chris@1 375 float **t = alloca(sizeof(*t)*step);
Chris@1 376 int i,j,o;
Chris@1 377
Chris@1 378 for (i = 0; i < step; i++) {
Chris@1 379 entry[i]=decode_packed_entry_number(book,b);
Chris@1 380 if(entry[i]==-1)return(-1);
Chris@1 381 t[i] = book->valuelist+entry[i]*book->dim;
Chris@1 382 }
Chris@1 383 for(i=0,o=0;i<book->dim;i++,o+=step)
Chris@1 384 for (j=0;j<step;j++)
Chris@1 385 a[o+j]+=t[j][i];
Chris@1 386 }
Chris@1 387 return(0);
Chris@1 388 }
Chris@1 389
Chris@1 390 /* decode vector / dim granularity gaurding is done in the upper layer */
Chris@1 391 long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){
Chris@1 392 if(book->used_entries>0){
Chris@1 393 int i,j,entry;
Chris@1 394 float *t;
Chris@1 395
Chris@1 396 if(book->dim>8){
Chris@1 397 for(i=0;i<n;){
Chris@1 398 entry = decode_packed_entry_number(book,b);
Chris@1 399 if(entry==-1)return(-1);
Chris@1 400 t = book->valuelist+entry*book->dim;
Chris@1 401 for (j=0;j<book->dim;)
Chris@1 402 a[i++]+=t[j++];
Chris@1 403 }
Chris@1 404 }else{
Chris@1 405 for(i=0;i<n;){
Chris@1 406 entry = decode_packed_entry_number(book,b);
Chris@1 407 if(entry==-1)return(-1);
Chris@1 408 t = book->valuelist+entry*book->dim;
Chris@1 409 j=0;
Chris@1 410 switch((int)book->dim){
Chris@1 411 case 8:
Chris@1 412 a[i++]+=t[j++];
Chris@1 413 case 7:
Chris@1 414 a[i++]+=t[j++];
Chris@1 415 case 6:
Chris@1 416 a[i++]+=t[j++];
Chris@1 417 case 5:
Chris@1 418 a[i++]+=t[j++];
Chris@1 419 case 4:
Chris@1 420 a[i++]+=t[j++];
Chris@1 421 case 3:
Chris@1 422 a[i++]+=t[j++];
Chris@1 423 case 2:
Chris@1 424 a[i++]+=t[j++];
Chris@1 425 case 1:
Chris@1 426 a[i++]+=t[j++];
Chris@1 427 case 0:
Chris@1 428 break;
Chris@1 429 }
Chris@1 430 }
Chris@1 431 }
Chris@1 432 }
Chris@1 433 return(0);
Chris@1 434 }
Chris@1 435
Chris@1 436 /* unlike the others, we guard against n not being an integer number
Chris@1 437 of <dim> internally rather than in the upper layer (called only by
Chris@1 438 floor0) */
Chris@1 439 long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
Chris@1 440 if(book->used_entries>0){
Chris@1 441 int i,j,entry;
Chris@1 442 float *t;
Chris@1 443
Chris@1 444 for(i=0;i<n;){
Chris@1 445 entry = decode_packed_entry_number(book,b);
Chris@1 446 if(entry==-1)return(-1);
Chris@1 447 t = book->valuelist+entry*book->dim;
Chris@1 448 for (j=0;i<n && j<book->dim;){
Chris@1 449 a[i++]=t[j++];
Chris@1 450 }
Chris@1 451 }
Chris@1 452 }else{
Chris@1 453 int i,j;
Chris@1 454
Chris@1 455 for(i=0;i<n;){
Chris@1 456 a[i++]=0.f;
Chris@1 457 }
Chris@1 458 }
Chris@1 459 return(0);
Chris@1 460 }
Chris@1 461
Chris@1 462 long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch,
Chris@1 463 oggpack_buffer *b,int n){
Chris@1 464
Chris@1 465 long i,j,entry;
Chris@1 466 int chptr=0;
Chris@1 467 if(book->used_entries>0){
Chris@1 468 for(i=offset/ch;i<(offset+n)/ch;){
Chris@1 469 entry = decode_packed_entry_number(book,b);
Chris@1 470 if(entry==-1)return(-1);
Chris@1 471 {
Chris@1 472 const float *t = book->valuelist+entry*book->dim;
Chris@1 473 for (j=0;j<book->dim;j++){
Chris@1 474 a[chptr++][i]+=t[j];
Chris@1 475 if(chptr==ch){
Chris@1 476 chptr=0;
Chris@1 477 i++;
Chris@1 478 }
Chris@1 479 }
Chris@1 480 }
Chris@1 481 }
Chris@1 482 }
Chris@1 483 return(0);
Chris@1 484 }