Coverage Report

Created: 2026-09-14 07:07

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
18.1k
static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
29
18.1k
  long i,j;
30
18.1k
  static_codebook *s=_ogg_calloc(1,sizeof(*s));
31
32
  /* make sure alignment is correct */
33
18.1k
  if(oggpack_read(opb,24)!=0x564342)goto _eofout;
34
35
  /* first the basic parameters */
36
18.0k
  s->dim=oggpack_read(opb,16);
37
18.0k
  s->entries=oggpack_read(opb,24);
38
18.0k
  if(s->entries==-1)goto _eofout;
39
40
18.0k
  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
41
42
  /* codeword ordering.... length ordered or unordered? */
43
17.9k
  switch((int)oggpack_read(opb,1)){
44
14.0k
  case 0:{
45
14.0k
    long unused;
46
    /* allocated but unused entries? */
47
14.0k
    unused=oggpack_read(opb,1);
48
14.0k
    if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
49
86
      goto _eofout;
50
    /* unordered */
51
13.9k
    s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
52
53
    /* allocated but unused entries? */
54
13.9k
    if(unused){
55
      /* yes, unused entries */
56
57
868k
      for(i=0;i<s->entries;i++){
58
857k
  if(oggpack_read(opb,1)){
59
288k
    long num=oggpack_read(opb,5);
60
288k
    if(num==-1)goto _eofout;
61
288k
    s->lengthlist[i]=num+1;
62
288k
  }else
63
568k
    s->lengthlist[i]=0;
64
857k
      }
65
11.9k
    }else{
66
      /* all entries used; no tagging */
67
159k
      for(i=0;i<s->entries;i++){
68
157k
  long num=oggpack_read(opb,5);
69
157k
  if(num==-1)goto _eofout;
70
157k
  s->lengthlist[i]=num+1;
71
157k
      }
72
2.05k
    }
73
    
74
13.9k
    break;
75
13.9k
  }
76
13.9k
  case 1:
77
    /* ordered */
78
3.91k
    {
79
3.91k
      long length=oggpack_read(opb,5)+1;
80
3.91k
      if(length==0)goto _eofout;
81
3.91k
      s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
82
83
15.0k
      for(i=0;i<s->entries;){
84
11.3k
  long num=oggpack_read(opb,_ilog(s->entries-i));
85
11.3k
  if(num==-1)goto _eofout;
86
11.2k
  if(length>32 || num>s->entries-i ||
87
11.1k
     (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
88
107
    goto _errout;
89
107
  }
90
235M
  for(j=0;j<num;j++,i++)
91
235M
    s->lengthlist[i]=length;
92
11.1k
  length++;
93
11.1k
      }
94
3.91k
    }
95
3.73k
    break;
96
3.73k
  default:
97
    /* EOF */
98
19
    goto _eofout;
99
17.9k
  }
100
  
101
  /* Do we have a mapping to unpack? */
102
17.6k
  switch((s->maptype=oggpack_read(opb,4))){
103
8.35k
  case 0:
104
    /* no mapping */
105
8.35k
    break;
106
9.27k
  case 1: case 2:
107
    /* implicitly populated value mapping */
108
    /* explicitly populated value mapping */
109
110
9.27k
    s->q_min=oggpack_read(opb,32);
111
9.27k
    s->q_delta=oggpack_read(opb,32);
112
9.27k
    s->q_quant=oggpack_read(opb,4)+1;
113
9.27k
    s->q_sequencep=oggpack_read(opb,1);
114
9.27k
    if(s->q_sequencep==-1)goto _eofout;
115
116
9.25k
    {
117
9.25k
      int quantvals=0;
118
9.25k
      switch(s->maptype){
119
6.46k
      case 1:
120
6.46k
  quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
121
6.46k
  break;
122
2.79k
      case 2:
123
2.79k
  quantvals=s->entries*s->dim;
124
2.79k
  break;
125
9.25k
      }
126
      
127
      /* quantized values */
128
9.25k
      if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
129
133
        goto _eofout;
130
9.11k
      s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
131
175k
      for(i=0;i<quantvals;i++)
132
166k
  s->quantlist[i]=oggpack_read(opb,s->q_quant);
133
      
134
9.11k
      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
135
9.11k
    }
136
9.11k
    break;
137
9.11k
  default:
138
51
    goto _errout;
139
17.6k
  }
140
141
  /* all set */
142
17.4k
  return(s);
143
  
144
158
 _errout:
145
715
 _eofout:
146
715
  vorbis_staticbook_destroy(s);
147
715
  return(NULL); 
148
158
}
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
328k
static ogg_uint32_t bitreverse(ogg_uint32_t x){
159
328k
  x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
160
328k
  x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
161
328k
  x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
162
328k
  x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
163
328k
  return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
164
328k
}
165
166
STIN long decode_packed_entry_number(codebook *book, 
167
844k
                oggpack_buffer *b){
168
844k
  int  read=book->dec_maxlength;
169
844k
  long lo,hi;
170
844k
  long lok = oggpack_look(b,book->dec_firsttablen);
171
 
172
844k
  if (lok >= 0) {
173
816k
    long entry = book->dec_firsttable[lok];
174
816k
    if(entry&0x80000000UL){
175
309k
      lo=(entry>>15)&0x7fff;
176
309k
      hi=book->used_entries-(entry&0x7fff);
177
506k
    }else{
178
506k
      oggpack_adv(b, book->dec_codelengths[entry-1]);
179
506k
      return(entry-1);
180
506k
    }
181
816k
  }else{
182
28.0k
    lo=0;
183
28.0k
    hi=book->used_entries;
184
28.0k
  }
185
186
337k
  lok = oggpack_look(b, read);
187
188
381k
  while(lok<0 && read>1)
189
43.4k
    lok = oggpack_look(b, --read);
190
191
337k
  if(lok<0){
192
9.93k
    oggpack_adv(b,1); /* force eop */
193
9.93k
    return -1;
194
9.93k
  }
195
196
  /* bisect search for the codeword in the ordered list */
197
328k
  {
198
328k
    ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
199
200
368k
    while(hi-lo>1){
201
40.4k
      long p=(hi-lo)>>1;
202
40.4k
      long test=book->codelist[lo+p]>testword;    
203
40.4k
      lo+=p&(test-1);
204
40.4k
      hi-=p&(-test);
205
40.4k
    }
206
207
328k
    if(book->dec_codelengths[lo]<=read){
208
324k
      oggpack_adv(b, book->dec_codelengths[lo]);
209
324k
      return(lo);
210
324k
    }
211
328k
  }
212
  
213
3.68k
  oggpack_adv(b, read+1);
214
3.68k
  return(-1);
215
328k
}
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
327k
long vorbis_book_decode(codebook *book, oggpack_buffer *b){
233
327k
  if(book->used_entries>0){
234
326k
    long packed_entry=decode_packed_entry_number(book,b);
235
326k
    if(packed_entry>=0)
236
320k
      return(book->dec_index[packed_entry]);
237
326k
  }
238
239
  /* if there's no dec_index, the codebook unpacking isn't collapsed */
240
6.42k
  return(-1);
241
327k
}
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
69.6k
            oggpack_buffer *b,int n,int point){
247
69.6k
  if(book->used_entries>0){  
248
68.1k
    int step=n/book->dim;
249
68.1k
    long *entry = (long *)alloca(sizeof(*entry)*step);
250
68.1k
    ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
251
68.1k
    int i,j,o;
252
68.1k
    int shift=point-book->binarypoint;
253
    
254
68.1k
    if(shift>=0){
255
60.1k
      for (i = 0; i < step; i++) {
256
16.0k
  entry[i]=decode_packed_entry_number(book,b);
257
16.0k
  if(entry[i]==-1)return(-1);
258
15.2k
  t[i] = book->valuelist+entry[i]*book->dim;
259
15.2k
      }
260
1.09G
      for(i=0,o=0;i<book->dim;i++,o+=step)
261
1.09G
  for (j=0;o+j<n && j<step;j++)
262
387k
    a[o+j]+=t[j][i]>>shift;
263
44.0k
    }else{
264
35.4k
      for (i = 0; i < step; i++) {
265
12.7k
  entry[i]=decode_packed_entry_number(book,b);
266
12.7k
  if(entry[i]==-1)return(-1);
267
12.2k
  t[i] = book->valuelist+entry[i]*book->dim;
268
12.2k
      }
269
525M
      for(i=0,o=0;i<book->dim;i++,o+=step)
270
526M
  for (j=0;o+j<n && j<step;j++)
271
270k
    a[o+j]+=t[j][i]<<-shift;
272
22.7k
    }
273
68.1k
  }
274
68.2k
  return(0);
275
69.6k
}
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
24.3k
           oggpack_buffer *b,int n,int point){
280
24.3k
  if(book->used_entries>0){
281
23.9k
    int i,j,entry;
282
23.9k
    ogg_int32_t *t;
283
23.9k
    int shift=point-book->binarypoint;
284
    
285
23.9k
    if(shift>=0){
286
139k
      for(i=0;i<n;){
287
131k
  entry = decode_packed_entry_number(book,b);
288
131k
  if(entry==-1)return(-1);
289
130k
  t     = book->valuelist+entry*book->dim;
290
969k
  for (j=0;i<n && j<book->dim;)
291
839k
    a[i++]+=t[j++]>>shift;
292
130k
      }
293
15.1k
    }else{
294
71.9k
      for(i=0;i<n;){
295
57.5k
  entry = decode_packed_entry_number(book,b);
296
57.5k
  if(entry==-1)return(-1);
297
56.8k
  t     = book->valuelist+entry*book->dim;
298
653k
  for (j=0;i<n && j<book->dim;)
299
596k
    a[i++]+=t[j++]<<-shift;
300
56.8k
      }
301
15.1k
    }
302
23.9k
  }
303
22.2k
  return(0);
304
24.3k
}
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
32.4k
           oggpack_buffer *b,int n,int point){
311
32.4k
  if(book->used_entries>0){
312
30.4k
    int i,j,entry;
313
30.4k
    ogg_int32_t *t;
314
30.4k
    int shift=point-book->binarypoint;
315
    
316
30.4k
    if(shift>=0){
317
      
318
201k
      for(i=0;i<n;){
319
183k
  entry = decode_packed_entry_number(book,b);
320
183k
  if(entry==-1)return(-1);
321
181k
  t     = book->valuelist+entry*book->dim;
322
1.60M
  for (j=0;i<n && j<book->dim;){
323
1.42M
    a[i++]=t[j++]>>shift;
324
1.42M
  }
325
181k
      }
326
20.1k
    }else{
327
      
328
87.7k
      for(i=0;i<n;){
329
78.4k
  entry = decode_packed_entry_number(book,b);
330
78.4k
  if(entry==-1)return(-1);
331
77.4k
  t     = book->valuelist+entry*book->dim;
332
949k
  for (j=0;i<n && j<book->dim;){
333
872k
    a[i++]=t[j++]<<-shift;
334
872k
  }
335
77.4k
      }
336
10.2k
    }
337
30.4k
  }else{
338
339
1.97k
    int i;
340
220k
    for(i=0;i<n;){
341
218k
      a[i++]=0;
342
218k
    }
343
1.97k
  }
344
29.2k
  return(0);
345
32.4k
}
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.04M
            oggpack_buffer *b,int n,int point){
351
1.04M
  if(book->used_entries>0){
352
1.04M
    long i,j,entry;
353
1.04M
    int chptr=0;
354
1.04M
    int shift=point-book->binarypoint;
355
1.04M
    int m=offset+n;
356
1.04M
    if(shift>=0){
357
      
358
736k
      for(i=offset;i<m;){
359
21.9k
  entry = decode_packed_entry_number(book,b);
360
21.9k
  if(entry==-1)return(-1);
361
21.1k
  {
362
21.1k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
363
1.46M
    for (j=0;i<m && j<book->dim;j++){
364
1.44M
      a[chptr++][i]+=t[j]>>shift;
365
1.44M
      if(chptr==ch){
366
295k
        chptr=0;
367
295k
        i++;
368
295k
      }
369
1.44M
    }
370
21.1k
  }
371
21.1k
      }
372
715k
    }else{
373
      
374
345k
      for(i=offset;i<m;){
375
15.9k
  entry = decode_packed_entry_number(book,b);
376
15.9k
  if(entry==-1)return(-1);
377
15.2k
  {
378
15.2k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
379
1.41M
    for (j=0;i<m && j<book->dim;j++){
380
1.40M
      a[chptr++][i]+=t[j]<<-shift;
381
1.40M
      if(chptr==ch){
382
292k
        chptr=0;
383
292k
        i++;
384
292k
      }
385
1.40M
    }
386
15.2k
  }
387
15.2k
      }
388
330k
    }
389
1.04M
  }
390
1.04M
  return(0);
391
1.04M
}