Coverage Report

Created: 2026-01-17 06:57

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
44
      goto _eofout;
50
    /* unordered */
51
13.2k
    s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
52
53
    /* allocated but unused entries? */
54
13.2k
    if(unused){
55
      /* yes, unused entries */
56
57
777k
      for(i=0;i<s->entries;i++){
58
766k
  if(oggpack_read(opb,1)){
59
327k
    long num=oggpack_read(opb,5);
60
327k
    if(num==-1)goto _eofout;
61
327k
    s->lengthlist[i]=num+1;
62
327k
  }else
63
438k
    s->lengthlist[i]=0;
64
766k
      }
65
11.0k
    }else{
66
      /* all entries used; no tagging */
67
272k
      for(i=0;i<s->entries;i++){
68
270k
  long num=oggpack_read(opb,5);
69
270k
  if(num==-1)goto _eofout;
70
270k
  s->lengthlist[i]=num+1;
71
270k
      }
72
2.14k
    }
73
    
74
13.2k
    break;
75
13.2k
  }
76
13.2k
  case 1:
77
    /* ordered */
78
2.37k
    {
79
2.37k
      long length=oggpack_read(opb,5)+1;
80
2.37k
      if(length==0)goto _eofout;
81
2.37k
      s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
82
83
6.76k
      for(i=0;i<s->entries;){
84
4.48k
  long num=oggpack_read(opb,_ilog(s->entries-i));
85
4.48k
  if(num==-1)goto _eofout;
86
4.45k
  if(length>32 || num>s->entries-i ||
87
4.42k
     (num>0 && (num-1)>>(length>>1)>>((length+1)>>1))>0){
88
64
    goto _errout;
89
64
  }
90
147M
  for(j=0;j<num;j++,i++)
91
147M
    s->lengthlist[i]=length;
92
4.39k
  length++;
93
4.39k
      }
94
2.37k
    }
95
2.28k
    break;
96
2.28k
  default:
97
    /* EOF */
98
4
    goto _eofout;
99
15.6k
  }
100
  
101
  /* Do we have a mapping to unpack? */
102
15.5k
  switch((s->maptype=oggpack_read(opb,4))){
103
7.99k
  case 0:
104
    /* no mapping */
105
7.99k
    break;
106
7.48k
  case 1: case 2:
107
    /* implicitly populated value mapping */
108
    /* explicitly populated value mapping */
109
110
7.48k
    s->q_min=oggpack_read(opb,32);
111
7.48k
    s->q_delta=oggpack_read(opb,32);
112
7.48k
    s->q_quant=oggpack_read(opb,4)+1;
113
7.48k
    s->q_sequencep=oggpack_read(opb,1);
114
7.48k
    if(s->q_sequencep==-1)goto _eofout;
115
116
7.47k
    {
117
7.47k
      int quantvals=0;
118
7.47k
      switch(s->maptype){
119
5.50k
      case 1:
120
5.50k
  quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
121
5.50k
  break;
122
1.97k
      case 2:
123
1.97k
  quantvals=s->entries*s->dim;
124
1.97k
  break;
125
7.47k
      }
126
      
127
      /* quantized values */
128
7.47k
      if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb))
129
36
        goto _eofout;
130
7.44k
      s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
131
88.8k
      for(i=0;i<quantvals;i++)
132
81.4k
  s->quantlist[i]=oggpack_read(opb,s->q_quant);
133
      
134
7.44k
      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
135
7.44k
    }
136
7.44k
    break;
137
7.44k
  default:
138
26
    goto _errout;
139
15.5k
  }
140
141
  /* all set */
142
15.4k
  return(s);
143
  
144
90
 _errout:
145
328
 _eofout:
146
328
  vorbis_staticbook_destroy(s);
147
328
  return(NULL); 
148
90
}
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
136k
static ogg_uint32_t bitreverse(ogg_uint32_t x){
159
136k
  x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
160
136k
  x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
161
136k
  x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
162
136k
  x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
163
136k
  return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
164
136k
}
165
166
STIN long decode_packed_entry_number(codebook *book, 
167
331k
                oggpack_buffer *b){
168
331k
  int  read=book->dec_maxlength;
169
331k
  long lo,hi;
170
331k
  long lok = oggpack_look(b,book->dec_firsttablen);
171
 
172
331k
  if (lok >= 0) {
173
313k
    long entry = book->dec_firsttable[lok];
174
313k
    if(entry&0x80000000UL){
175
125k
      lo=(entry>>15)&0x7fff;
176
125k
      hi=book->used_entries-(entry&0x7fff);
177
188k
    }else{
178
188k
      oggpack_adv(b, book->dec_codelengths[entry-1]);
179
188k
      return(entry-1);
180
188k
    }
181
313k
  }else{
182
17.4k
    lo=0;
183
17.4k
    hi=book->used_entries;
184
17.4k
  }
185
186
143k
  lok = oggpack_look(b, read);
187
188
166k
  while(lok<0 && read>1)
189
23.7k
    lok = oggpack_look(b, --read);
190
191
143k
  if(lok<0){
192
6.84k
    oggpack_adv(b,1); /* force eop */
193
6.84k
    return -1;
194
6.84k
  }
195
196
  /* bisect search for the codeword in the ordered list */
197
136k
  {
198
136k
    ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
199
200
161k
    while(hi-lo>1){
201
25.4k
      long p=(hi-lo)>>1;
202
25.4k
      long test=book->codelist[lo+p]>testword;    
203
25.4k
      lo+=p&(test-1);
204
25.4k
      hi-=p&(-test);
205
25.4k
    }
206
207
136k
    if(book->dec_codelengths[lo]<=read){
208
135k
      oggpack_adv(b, book->dec_codelengths[lo]);
209
135k
      return(lo);
210
135k
    }
211
136k
  }
212
  
213
1.03k
  oggpack_adv(b, read+1);
214
1.03k
  return(-1);
215
136k
}
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
60.8k
long vorbis_book_decode(codebook *book, oggpack_buffer *b){
233
60.8k
  if(book->used_entries>0){
234
60.3k
    long packed_entry=decode_packed_entry_number(book,b);
235
60.3k
    if(packed_entry>=0)
236
56.5k
      return(book->dec_index[packed_entry]);
237
60.3k
  }
238
239
  /* if there's no dec_index, the codebook unpacking isn't collapsed */
240
4.34k
  return(-1);
241
60.8k
}
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
54.2k
            oggpack_buffer *b,int n,int point){
247
54.2k
  if(book->used_entries>0){  
248
53.8k
    int step=n/book->dim;
249
53.8k
    long *entry = (long *)alloca(sizeof(*entry)*step);
250
53.8k
    ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
251
53.8k
    int i,j,o;
252
53.8k
    int shift=point-book->binarypoint;
253
    
254
53.8k
    if(shift>=0){
255
33.7k
      for (i = 0; i < step; i++) {
256
10.6k
  entry[i]=decode_packed_entry_number(book,b);
257
10.6k
  if(entry[i]==-1)return(-1);
258
10.3k
  t[i] = book->valuelist+entry[i]*book->dim;
259
10.3k
      }
260
262M
      for(i=0,o=0;i<book->dim;i++,o+=step)
261
262M
  for (j=0;o+j<n && j<step;j++)
262
176k
    a[o+j]+=t[j][i]>>shift;
263
30.4k
    }else{
264
54.2k
      for (i = 0; i < step; i++) {
265
24.2k
  entry[i]=decode_packed_entry_number(book,b);
266
24.2k
  if(entry[i]==-1)return(-1);
267
23.7k
  t[i] = book->valuelist+entry[i]*book->dim;
268
23.7k
      }
269
231M
      for(i=0,o=0;i<book->dim;i++,o+=step)
270
231M
  for (j=0;o+j<n && j<step;j++)
271
421k
    a[o+j]+=t[j][i]<<-shift;
272
30.0k
    }
273
53.8k
  }
274
53.5k
  return(0);
275
54.2k
}
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
14.4k
           oggpack_buffer *b,int n,int point){
280
14.4k
  if(book->used_entries>0){
281
14.1k
    int i,j,entry;
282
14.1k
    ogg_int32_t *t;
283
14.1k
    int shift=point-book->binarypoint;
284
    
285
14.1k
    if(shift>=0){
286
40.3k
      for(i=0;i<n;){
287
31.1k
  entry = decode_packed_entry_number(book,b);
288
31.1k
  if(entry==-1)return(-1);
289
30.5k
  t     = book->valuelist+entry*book->dim;
290
329k
  for (j=0;i<n && j<book->dim;)
291
298k
    a[i++]+=t[j++]>>shift;
292
30.5k
      }
293
9.74k
    }else{
294
65.5k
      for(i=0;i<n;){
295
62.0k
  entry = decode_packed_entry_number(book,b);
296
62.0k
  if(entry==-1)return(-1);
297
61.1k
  t     = book->valuelist+entry*book->dim;
298
670k
  for (j=0;i<n && j<book->dim;)
299
609k
    a[i++]+=t[j++]<<-shift;
300
61.1k
      }
301
4.41k
    }
302
14.1k
  }
303
12.9k
  return(0);
304
14.4k
}
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
16.4k
           oggpack_buffer *b,int n,int point){
311
16.4k
  if(book->used_entries>0){
312
15.7k
    int i,j,entry;
313
15.7k
    ogg_int32_t *t;
314
15.7k
    int shift=point-book->binarypoint;
315
    
316
15.7k
    if(shift>=0){
317
      
318
92.3k
      for(i=0;i<n;){
319
84.8k
  entry = decode_packed_entry_number(book,b);
320
84.8k
  if(entry==-1)return(-1);
321
84.2k
  t     = book->valuelist+entry*book->dim;
322
553k
  for (j=0;i<n && j<book->dim;){
323
469k
    a[i++]=t[j++]>>shift;
324
469k
  }
325
84.2k
      }
326
8.06k
    }else{
327
      
328
27.1k
      for(i=0;i<n;){
329
19.9k
  entry = decode_packed_entry_number(book,b);
330
19.9k
  if(entry==-1)return(-1);
331
19.4k
  t     = book->valuelist+entry*book->dim;
332
417k
  for (j=0;i<n && j<book->dim;){
333
398k
    a[i++]=t[j++]<<-shift;
334
398k
  }
335
19.4k
      }
336
7.67k
    }
337
15.7k
  }else{
338
339
757
    int i;
340
41.1k
    for(i=0;i<n;){
341
40.3k
      a[i++]=0;
342
40.3k
    }
343
757
  }
344
15.3k
  return(0);
345
16.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
304k
            oggpack_buffer *b,int n,int point){
351
304k
  if(book->used_entries>0){
352
303k
    long i,j,entry;
353
303k
    int chptr=0;
354
303k
    int shift=point-book->binarypoint;
355
303k
    int m=offset+n;
356
303k
    if(shift>=0){
357
      
358
214k
      for(i=offset;i<m;){
359
16.7k
  entry = decode_packed_entry_number(book,b);
360
16.7k
  if(entry==-1)return(-1);
361
16.3k
  {
362
16.3k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
363
1.41M
    for (j=0;i<m && j<book->dim;j++){
364
1.39M
      a[chptr++][i]+=t[j]>>shift;
365
1.39M
      if(chptr==ch){
366
130k
        chptr=0;
367
130k
        i++;
368
130k
      }
369
1.39M
    }
370
16.3k
  }
371
16.3k
      }
372
197k
    }else{
373
      
374
127k
      for(i=offset;i<m;){
375
21.2k
  entry = decode_packed_entry_number(book,b);
376
21.2k
  if(entry==-1)return(-1);
377
20.9k
  {
378
20.9k
    const ogg_int32_t *t = book->valuelist+entry*book->dim;
379
1.46M
    for (j=0;i<m && j<book->dim;j++){
380
1.44M
      a[chptr++][i]+=t[j]<<-shift;
381
1.44M
      if(chptr==ch){
382
102k
        chptr=0;
383
102k
        i++;
384
102k
      }
385
1.44M
    }
386
20.9k
  }
387
20.9k
      }
388
106k
    }
389
303k
  }
390
303k
  return(0);
391
304k
}