Coverage Report

Created: 2026-01-10 06:31

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