Coverage Report

Created: 2025-11-24 06:18

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
13.7k
static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
29
13.7k
  long i,j;
30
13.7k
  static_codebook *s=_ogg_calloc(1,sizeof(*s));
31
32
  /* make sure alignment is correct */
33
13.7k
  if(oggpack_read(opb,24)!=0x564342)goto _eofout;
34
35
  /* first the basic parameters */
36
13.6k
  s->dim=oggpack_read(opb,16);
37
13.6k
  s->entries=oggpack_read(opb,24);
38
13.6k
  if(s->entries==-1)goto _eofout;
39
40
13.6k
  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
41
42
  /* codeword ordering.... length ordered or unordered? */
43
13.6k
  switch((int)oggpack_read(opb,1)){
44
11.6k
  case 0:{
45
11.6k
    long unused;
46
    /* allocated but unused entries? */
47
11.6k
    unused=oggpack_read(opb,1);
48
11.6k
    if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
49
39
      goto _eofout;
50
    /* unordered */
51
11.5k
    s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
52
53
    /* allocated but unused entries? */
54
11.5k
    if(unused){
55
      /* yes, unused entries */
56
57
745k
      for(i=0;i<s->entries;i++){
58
735k
  if(oggpack_read(opb,1)){
59
313k
    long num=oggpack_read(opb,5);
60
313k
    if(num==-1)goto _eofout;
61
313k
    s->lengthlist[i]=num+1;
62
313k
  }else
63
422k
    s->lengthlist[i]=0;
64
735k
      }
65
9.66k
    }else{
66
      /* all entries used; no tagging */
67
175k
      for(i=0;i<s->entries;i++){
68
173k
  long num=oggpack_read(opb,5);
69
173k
  if(num==-1)goto _eofout;
70
173k
  s->lengthlist[i]=num+1;
71
173k
      }
72
1.90k
    }
73
    
74
11.5k
    break;
75
11.5k
  }
76
11.5k
  case 1:
77
    /* ordered */
78
2.03k
    {
79
2.03k
      long length=oggpack_read(opb,5)+1;
80
2.03k
      if(length==0)goto _eofout;
81
2.03k
      s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
82
83
5.88k
      for(i=0;i<s->entries;){
84
3.93k
  long num=oggpack_read(opb,_ilog(s->entries-i));
85
3.93k
  if(num==-1)goto _eofout;
86
3.91k
  if(length>32 || num>s->entries-i ||
87
3.87k
     (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
88
60
    goto _errout;
89
60
  }
90
195M
  for(j=0;j<num;j++,i++)
91
195M
    s->lengthlist[i]=length;
92
3.85k
  length++;
93
3.85k
      }
94
2.03k
    }
95
1.95k
    break;
96
1.95k
  default:
97
    /* EOF */
98
2
    goto _eofout;
99
13.6k
  }
100
  
101
  /* Do we have a mapping to unpack? */
102
13.5k
  switch((s->maptype=oggpack_read(opb,4))){
103
6.89k
  case 0:
104
    /* no mapping */
105
6.89k
    break;
106
6.59k
  case 1: case 2:
107
    /* implicitly populated value mapping */
108
    /* explicitly populated value mapping */
109
110
6.59k
    s->q_min=oggpack_read(opb,32);
111
6.59k
    s->q_delta=oggpack_read(opb,32);
112
6.59k
    s->q_quant=oggpack_read(opb,4)+1;
113
6.59k
    s->q_sequencep=oggpack_read(opb,1);
114
6.59k
    if(s->q_sequencep==-1)goto _eofout;
115
116
6.58k
    {
117
6.58k
      int quantvals=0;
118
6.58k
      switch(s->maptype){
119
4.55k
      case 1:
120
4.55k
  quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
121
4.55k
  break;
122
2.03k
      case 2:
123
2.03k
  quantvals=s->entries*s->dim;
124
2.03k
  break;
125
6.58k
      }
126
      
127
      /* quantized values */
128
6.58k
      if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
129
24
        goto _eofout;
130
6.56k
      s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
131
75.1k
      for(i=0;i<quantvals;i++)
132
68.5k
  s->quantlist[i]=oggpack_read(opb,s->q_quant);
133
      
134
6.56k
      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
135
6.56k
    }
136
6.56k
    break;
137
6.56k
  default:
138
24
    goto _errout;
139
13.5k
  }
140
141
  /* all set */
142
13.4k
  return(s);
143
  
144
84
 _errout:
145
282
 _eofout:
146
282
  vorbis_staticbook_destroy(s);
147
282
  return(NULL); 
148
84
}
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
157k
static ogg_uint32_t bitreverse(ogg_uint32_t x){
159
157k
  x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
160
157k
  x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
161
157k
  x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
162
157k
  x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
163
157k
  return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
164
157k
}
165
166
STIN long decode_packed_entry_number(codebook *book, 
167
385k
                oggpack_buffer *b){
168
385k
  int  read=book->dec_maxlength;
169
385k
  long lo,hi;
170
385k
  long lok = oggpack_look(b,book->dec_firsttablen);
171
 
172
385k
  if (lok >= 0) {
173
365k
    long entry = book->dec_firsttable[lok];
174
365k
    if(entry&0x80000000UL){
175
144k
      lo=(entry>>15)&0x7fff;
176
144k
      hi=book->used_entries-(entry&0x7fff);
177
220k
    }else{
178
220k
      oggpack_adv(b, book->dec_codelengths[entry-1]);
179
220k
      return(entry-1);
180
220k
    }
181
365k
  }else{
182
20.9k
    lo=0;
183
20.9k
    hi=book->used_entries;
184
20.9k
  }
185
186
165k
  lok = oggpack_look(b, read);
187
188
192k
  while(lok<0 && read>1)
189
26.9k
    lok = oggpack_look(b, --read);
190
191
165k
  if(lok<0){
192
7.92k
    oggpack_adv(b,1); /* force eop */
193
7.92k
    return -1;
194
7.92k
  }
195
196
  /* bisect search for the codeword in the ordered list */
197
157k
  {
198
157k
    ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
199
200
192k
    while(hi-lo>1){
201
34.4k
      long p=(hi-lo)>>1;
202
34.4k
      long test=book->codelist[lo+p]>testword;    
203
34.4k
      lo+=p&(test-1);
204
34.4k
      hi-=p&(-test);
205
34.4k
    }
206
207
157k
    if(book->dec_codelengths[lo]<=read){
208
156k
      oggpack_adv(b, book->dec_codelengths[lo]);
209
156k
      return(lo);
210
156k
    }
211
157k
  }
212
  
213
1.49k
  oggpack_adv(b, read+1);
214
1.49k
  return(-1);
215
157k
}
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
69.4k
long vorbis_book_decode(codebook *book, oggpack_buffer *b){
233
69.4k
  if(book->used_entries>0){
234
69.1k
    long packed_entry=decode_packed_entry_number(book,b);
235
69.1k
    if(packed_entry>=0)
236
65.0k
      return(book->dec_index[packed_entry]);
237
69.1k
  }
238
239
  /* if there's no dec_index, the codebook unpacking isn't collapsed */
240
4.38k
  return(-1);
241
69.4k
}
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
45.3k
            oggpack_buffer *b,int n,int point){
247
45.3k
  if(book->used_entries>0){  
248
44.1k
    int step=n/book->dim;
249
44.1k
    long *entry = (long *)alloca(sizeof(*entry)*step);
250
44.1k
    ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
251
44.1k
    int i,j,o;
252
44.1k
    int shift=point-book->binarypoint;
253
    
254
44.1k
    if(shift>=0){
255
45.8k
      for (i = 0; i < step; i++) {
256
15.8k
  entry[i]=decode_packed_entry_number(book,b);
257
15.8k
  if(entry[i]==-1)return(-1);
258
15.4k
  t[i] = book->valuelist+entry[i]*book->dim;
259
15.4k
      }
260
550M
      for(i=0,o=0;i<book->dim;i++,o+=step)
261
550M
  for (j=0;o+j<n && j<step;j++)
262
220k
    a[o+j]+=t[j][i]>>shift;
263
30.0k
    }else{
264
41.4k
      for (i = 0; i < step; i++) {
265
28.0k
  entry[i]=decode_packed_entry_number(book,b);
266
28.0k
  if(entry[i]==-1)return(-1);
267
27.7k
  t[i] = book->valuelist+entry[i]*book->dim;
268
27.7k
      }
269
407M
      for(i=0,o=0;i<book->dim;i++,o+=step)
270
407M
  for (j=0;o+j<n && j<step;j++)
271
239k
    a[o+j]+=t[j][i]<<-shift;
272
13.3k
    }
273
44.1k
  }
274
44.6k
  return(0);
275
45.3k
}
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
10.6k
           oggpack_buffer *b,int n,int point){
280
10.6k
  if(book->used_entries>0){
281
9.18k
    int i,j,entry;
282
9.18k
    ogg_int32_t *t;
283
9.18k
    int shift=point-book->binarypoint;
284
    
285
9.18k
    if(shift>=0){
286
12.5k
      for(i=0;i<n;){
287
9.26k
  entry = decode_packed_entry_number(book,b);
288
9.26k
  if(entry==-1)return(-1);
289
8.63k
  t     = book->valuelist+entry*book->dim;
290
233k
  for (j=0;i<n && j<book->dim;)
291
224k
    a[i++]+=t[j++]>>shift;
292
8.63k
      }
293
5.28k
    }else{
294
75.7k
      for(i=0;i<n;){
295
71.5k
  entry = decode_packed_entry_number(book,b);
296
71.5k
  if(entry==-1)return(-1);
297
70.5k
  t     = book->valuelist+entry*book->dim;
298
1.28M
  for (j=0;i<n && j<book->dim;)
299
1.21M
    a[i++]+=t[j++]<<-shift;
300
70.5k
      }
301
5.28k
    }
302
9.18k
  }
303
8.95k
  return(0);
304
10.6k
}
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
15.8k
           oggpack_buffer *b,int n,int point){
311
15.8k
  if(book->used_entries>0){
312
14.3k
    int i,j,entry;
313
14.3k
    ogg_int32_t *t;
314
14.3k
    int shift=point-book->binarypoint;
315
    
316
14.3k
    if(shift>=0){
317
      
318
129k
      for(i=0;i<n;){
319
120k
  entry = decode_packed_entry_number(book,b);
320
120k
  if(entry==-1)return(-1);
321
118k
  t     = book->valuelist+entry*book->dim;
322
882k
  for (j=0;i<n && j<book->dim;){
323
763k
    a[i++]=t[j++]>>shift;
324
763k
  }
325
118k
      }
326
10.2k
    }else{
327
      
328
19.7k
      for(i=0;i<n;){
329
16.1k
  entry = decode_packed_entry_number(book,b);
330
16.1k
  if(entry==-1)return(-1);
331
15.6k
  t     = book->valuelist+entry*book->dim;
332
358k
  for (j=0;i<n && j<book->dim;){
333
342k
    a[i++]=t[j++]<<-shift;
334
342k
  }
335
15.6k
      }
336
4.04k
    }
337
14.3k
  }else{
338
339
1.52k
    int i;
340
80.8k
    for(i=0;i<n;){
341
79.3k
      a[i++]=0;
342
79.3k
    }
343
1.52k
  }
344
13.9k
  return(0);
345
15.8k
}
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
2.08M
            oggpack_buffer *b,int n,int point){
351
2.08M
  if(book->used_entries>0){
352
2.08M
    long i,j,entry;
353
2.08M
    int chptr=0;
354
2.08M
    int shift=point-book->binarypoint;
355
2.08M
    int m=offset+n;
356
2.08M
    if(shift>=0){
357
      
358
691k
      for(i=offset;i<m;){
359
26.4k
  entry = decode_packed_entry_number(book,b);
360
26.4k
  if(entry==-1)return(-1);
361
25.9k
  {
362
25.9k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
363
450k
    for (j=0;i<m && j<book->dim;j++){
364
424k
      a[chptr++][i]+=t[j]>>shift;
365
424k
      if(chptr==ch){
366
145k
        chptr=0;
367
145k
        i++;
368
145k
      }
369
424k
    }
370
25.9k
  }
371
25.9k
      }
372
1.41M
    }else{
373
      
374
1.44M
      for(i=offset;i<m;){
375
29.1k
  entry = decode_packed_entry_number(book,b);
376
29.1k
  if(entry==-1)return(-1);
377
28.6k
  {
378
28.6k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
379
2.65M
    for (j=0;i<m && j<book->dim;j++){
380
2.62M
      a[chptr++][i]+=t[j]<<-shift;
381
2.62M
      if(chptr==ch){
382
110k
        chptr=0;
383
110k
        i++;
384
110k
      }
385
2.62M
    }
386
28.6k
  }
387
28.6k
      }
388
1.41M
    }
389
2.08M
  }
390
2.08M
  return(0);
391
2.08M
}