Coverage Report

Created: 2026-09-03 07:05

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
17.9k
static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
29
17.9k
  long i,j;
30
17.9k
  static_codebook *s=_ogg_calloc(1,sizeof(*s));
31
32
  /* make sure alignment is correct */
33
17.9k
  if(oggpack_read(opb,24)!=0x564342)goto _eofout;
34
35
  /* first the basic parameters */
36
17.7k
  s->dim=oggpack_read(opb,16);
37
17.7k
  s->entries=oggpack_read(opb,24);
38
17.7k
  if(s->entries==-1)goto _eofout;
39
40
17.7k
  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
41
42
  /* codeword ordering.... length ordered or unordered? */
43
17.7k
  switch((int)oggpack_read(opb,1)){
44
13.7k
  case 0:{
45
13.7k
    long unused;
46
    /* allocated but unused entries? */
47
13.7k
    unused=oggpack_read(opb,1);
48
13.7k
    if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
49
93
      goto _eofout;
50
    /* unordered */
51
13.6k
    s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
52
53
    /* allocated but unused entries? */
54
13.6k
    if(unused){
55
      /* yes, unused entries */
56
57
842k
      for(i=0;i<s->entries;i++){
58
831k
  if(oggpack_read(opb,1)){
59
324k
    long num=oggpack_read(opb,5);
60
324k
    if(num==-1)goto _eofout;
61
324k
    s->lengthlist[i]=num+1;
62
324k
  }else
63
506k
    s->lengthlist[i]=0;
64
831k
      }
65
11.5k
    }else{
66
      /* all entries used; no tagging */
67
270k
      for(i=0;i<s->entries;i++){
68
268k
  long num=oggpack_read(opb,5);
69
268k
  if(num==-1)goto _eofout;
70
268k
  s->lengthlist[i]=num+1;
71
268k
      }
72
2.11k
    }
73
    
74
13.6k
    break;
75
13.6k
  }
76
13.6k
  case 1:
77
    /* ordered */
78
4.00k
    {
79
4.00k
      long length=oggpack_read(opb,5)+1;
80
4.00k
      if(length==0)goto _eofout;
81
4.00k
      s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
82
83
16.2k
      for(i=0;i<s->entries;){
84
12.4k
  long num=oggpack_read(opb,_ilog(s->entries-i));
85
12.4k
  if(num==-1)goto _eofout;
86
12.3k
  if(length>32 || num>s->entries-i ||
87
12.2k
     (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
88
108
    goto _errout;
89
108
  }
90
300M
  for(j=0;j<num;j++,i++)
91
300M
    s->lengthlist[i]=length;
92
12.2k
  length++;
93
12.2k
      }
94
4.00k
    }
95
3.81k
    break;
96
3.81k
  default:
97
    /* EOF */
98
13
    goto _eofout;
99
17.7k
  }
100
  
101
  /* Do we have a mapping to unpack? */
102
17.4k
  switch((s->maptype=oggpack_read(opb,4))){
103
8.16k
  case 0:
104
    /* no mapping */
105
8.16k
    break;
106
9.21k
  case 1: case 2:
107
    /* implicitly populated value mapping */
108
    /* explicitly populated value mapping */
109
110
9.21k
    s->q_min=oggpack_read(opb,32);
111
9.21k
    s->q_delta=oggpack_read(opb,32);
112
9.21k
    s->q_quant=oggpack_read(opb,4)+1;
113
9.21k
    s->q_sequencep=oggpack_read(opb,1);
114
9.21k
    if(s->q_sequencep==-1)goto _eofout;
115
116
9.19k
    {
117
9.19k
      int quantvals=0;
118
9.19k
      switch(s->maptype){
119
6.40k
      case 1:
120
6.40k
  quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
121
6.40k
  break;
122
2.79k
      case 2:
123
2.79k
  quantvals=s->entries*s->dim;
124
2.79k
  break;
125
9.19k
      }
126
      
127
      /* quantized values */
128
9.19k
      if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
129
163
        goto _eofout;
130
9.03k
      s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
131
164k
      for(i=0;i<quantvals;i++)
132
155k
  s->quantlist[i]=oggpack_read(opb,s->q_quant);
133
      
134
9.03k
      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
135
9.03k
    }
136
9.03k
    break;
137
9.03k
  default:
138
43
    goto _errout;
139
17.4k
  }
140
141
  /* all set */
142
17.1k
  return(s);
143
  
144
151
 _errout:
145
767
 _eofout:
146
767
  vorbis_staticbook_destroy(s);
147
767
  return(NULL); 
148
151
}
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
261k
static ogg_uint32_t bitreverse(ogg_uint32_t x){
159
261k
  x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
160
261k
  x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
161
261k
  x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
162
261k
  x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
163
261k
  return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
164
261k
}
165
166
STIN long decode_packed_entry_number(codebook *book, 
167
1.11M
                oggpack_buffer *b){
168
1.11M
  int  read=book->dec_maxlength;
169
1.11M
  long lo,hi;
170
1.11M
  long lok = oggpack_look(b,book->dec_firsttablen);
171
 
172
1.11M
  if (lok >= 0) {
173
1.07M
    long entry = book->dec_firsttable[lok];
174
1.07M
    if(entry&0x80000000UL){
175
242k
      lo=(entry>>15)&0x7fff;
176
242k
      hi=book->used_entries-(entry&0x7fff);
177
837k
    }else{
178
837k
      oggpack_adv(b, book->dec_codelengths[entry-1]);
179
837k
      return(entry-1);
180
837k
    }
181
1.07M
  }else{
182
31.9k
    lo=0;
183
31.9k
    hi=book->used_entries;
184
31.9k
  }
185
186
274k
  lok = oggpack_look(b, read);
187
188
315k
  while(lok<0 && read>1)
189
40.8k
    lok = oggpack_look(b, --read);
190
191
274k
  if(lok<0){
192
12.2k
    oggpack_adv(b,1); /* force eop */
193
12.2k
    return -1;
194
12.2k
  }
195
196
  /* bisect search for the codeword in the ordered list */
197
261k
  {
198
261k
    ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
199
200
298k
    while(hi-lo>1){
201
36.9k
      long p=(hi-lo)>>1;
202
36.9k
      long test=book->codelist[lo+p]>testword;    
203
36.9k
      lo+=p&(test-1);
204
36.9k
      hi-=p&(-test);
205
36.9k
    }
206
207
261k
    if(book->dec_codelengths[lo]<=read){
208
258k
      oggpack_adv(b, book->dec_codelengths[lo]);
209
258k
      return(lo);
210
258k
    }
211
261k
  }
212
  
213
3.45k
  oggpack_adv(b, read+1);
214
3.45k
  return(-1);
215
261k
}
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
560k
long vorbis_book_decode(codebook *book, oggpack_buffer *b){
233
560k
  if(book->used_entries>0){
234
559k
    long packed_entry=decode_packed_entry_number(book,b);
235
559k
    if(packed_entry>=0)
236
552k
      return(book->dec_index[packed_entry]);
237
559k
  }
238
239
  /* if there's no dec_index, the codebook unpacking isn't collapsed */
240
8.04k
  return(-1);
241
560k
}
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
60.0k
            oggpack_buffer *b,int n,int point){
247
60.0k
  if(book->used_entries>0){  
248
58.2k
    int step=n/book->dim;
249
58.2k
    long *entry = (long *)alloca(sizeof(*entry)*step);
250
58.2k
    ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
251
58.2k
    int i,j,o;
252
58.2k
    int shift=point-book->binarypoint;
253
    
254
58.2k
    if(shift>=0){
255
49.2k
      for (i = 0; i < step; i++) {
256
14.8k
  entry[i]=decode_packed_entry_number(book,b);
257
14.8k
  if(entry[i]==-1)return(-1);
258
14.3k
  t[i] = book->valuelist+entry[i]*book->dim;
259
14.3k
      }
260
901M
      for(i=0,o=0;i<book->dim;i++,o+=step)
261
901M
  for (j=0;o+j<n && j<step;j++)
262
440k
    a[o+j]+=t[j][i]>>shift;
263
34.4k
    }else{
264
33.7k
      for (i = 0; i < step; i++) {
265
10.9k
  entry[i]=decode_packed_entry_number(book,b);
266
10.9k
  if(entry[i]==-1)return(-1);
267
10.4k
  t[i] = book->valuelist+entry[i]*book->dim;
268
10.4k
      }
269
395M
      for(i=0,o=0;i<book->dim;i++,o+=step)
270
395M
  for (j=0;o+j<n && j<step;j++)
271
230k
    a[o+j]+=t[j][i]<<-shift;
272
22.7k
    }
273
58.2k
  }
274
59.0k
  return(0);
275
60.0k
}
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
16.1k
           oggpack_buffer *b,int n,int point){
280
16.1k
  if(book->used_entries>0){
281
15.8k
    int i,j,entry;
282
15.8k
    ogg_int32_t *t;
283
15.8k
    int shift=point-book->binarypoint;
284
    
285
15.8k
    if(shift>=0){
286
134k
      for(i=0;i<n;){
287
126k
  entry = decode_packed_entry_number(book,b);
288
126k
  if(entry==-1)return(-1);
289
125k
  t     = book->valuelist+entry*book->dim;
290
1.07M
  for (j=0;i<n && j<book->dim;)
291
952k
    a[i++]+=t[j++]>>shift;
292
125k
      }
293
8.72k
    }else{
294
35.8k
      for(i=0;i<n;){
295
29.3k
  entry = decode_packed_entry_number(book,b);
296
29.3k
  if(entry==-1)return(-1);
297
28.6k
  t     = book->valuelist+entry*book->dim;
298
471k
  for (j=0;i<n && j<book->dim;)
299
442k
    a[i++]+=t[j++]<<-shift;
300
28.6k
      }
301
7.14k
    }
302
15.8k
  }
303
14.1k
  return(0);
304
16.1k
}
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
39.1k
           oggpack_buffer *b,int n,int point){
311
39.1k
  if(book->used_entries>0){
312
37.1k
    int i,j,entry;
313
37.1k
    ogg_int32_t *t;
314
37.1k
    int shift=point-book->binarypoint;
315
    
316
37.1k
    if(shift>=0){
317
      
318
270k
      for(i=0;i<n;){
319
245k
  entry = decode_packed_entry_number(book,b);
320
245k
  if(entry==-1)return(-1);
321
242k
  t     = book->valuelist+entry*book->dim;
322
1.94M
  for (j=0;i<n && j<book->dim;){
323
1.69M
    a[i++]=t[j++]>>shift;
324
1.69M
  }
325
242k
      }
326
27.3k
    }else{
327
      
328
47.6k
      for(i=0;i<n;){
329
38.6k
  entry = decode_packed_entry_number(book,b);
330
38.6k
  if(entry==-1)return(-1);
331
37.7k
  t     = book->valuelist+entry*book->dim;
332
930k
  for (j=0;i<n && j<book->dim;){
333
892k
    a[i++]=t[j++]<<-shift;
334
892k
  }
335
37.7k
      }
336
9.80k
    }
337
37.1k
  }else{
338
339
2.05k
    int i;
340
221k
    for(i=0;i<n;){
341
219k
      a[i++]=0;
342
219k
    }
343
2.05k
  }
344
35.3k
  return(0);
345
39.1k
}
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
1.36M
            oggpack_buffer *b,int n,int point){
351
1.36M
  if(book->used_entries>0){
352
1.36M
    long i,j,entry;
353
1.36M
    int chptr=0;
354
1.36M
    int shift=point-book->binarypoint;
355
1.36M
    int m=offset+n;
356
1.36M
    if(shift>=0){
357
      
358
1.16M
      for(i=offset;i<m;){
359
13.8k
  entry = decode_packed_entry_number(book,b);
360
13.8k
  if(entry==-1)return(-1);
361
13.0k
  {
362
13.0k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
363
2.37M
    for (j=0;i<m && j<book->dim;j++){
364
2.35M
      a[chptr++][i]+=t[j]>>shift;
365
2.35M
      if(chptr==ch){
366
371k
        chptr=0;
367
371k
        i++;
368
371k
      }
369
2.35M
    }
370
13.0k
  }
371
13.0k
      }
372
1.15M
    }else{
373
      
374
281k
      for(i=offset;i<m;){
375
71.9k
  entry = decode_packed_entry_number(book,b);
376
71.9k
  if(entry==-1)return(-1);
377
71.0k
  {
378
71.0k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
379
2.03M
    for (j=0;i<m && j<book->dim;j++){
380
1.96M
      a[chptr++][i]+=t[j]<<-shift;
381
1.96M
      if(chptr==ch){
382
413k
        chptr=0;
383
413k
        i++;
384
413k
      }
385
1.96M
    }
386
71.0k
  }
387
71.0k
      }
388
210k
    }
389
1.36M
  }
390
1.36M
  return(0);
391
1.36M
}