Coverage Report

Created: 2026-04-01 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tremor/res012.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: residue backend 0, 1 and 2 implementation
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 "codec_internal.h"
24
#include "registry.h"
25
#include "codebook.h"
26
#include "misc.h"
27
#include "os.h"
28
#include "block.h"
29
30
typedef struct {
31
  vorbis_info_residue0 *info;
32
  int         map;
33
  
34
  int         parts;
35
  int         stages;
36
  codebook   *fullbooks;
37
  codebook   *phrasebook;
38
  codebook ***partbooks;
39
40
  int         partvals;
41
  int       **decodemap;
42
43
} vorbis_look_residue0;
44
45
8.42k
void res0_free_info(vorbis_info_residue *i){
46
8.42k
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
47
8.42k
  if(info){
48
8.42k
    memset(info,0,sizeof(*info));
49
8.42k
    _ogg_free(info);
50
8.42k
  }
51
8.42k
}
52
53
10.0k
void res0_free_look(vorbis_look_residue *i){
54
10.0k
  int j;
55
10.0k
  if(i){
56
57
10.0k
    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
58
59
25.3k
    for(j=0;j<look->parts;j++)
60
15.2k
      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
61
10.0k
    _ogg_free(look->partbooks);
62
53.4k
    for(j=0;j<look->partvals;j++)
63
43.4k
      _ogg_free(look->decodemap[j]);
64
10.0k
    _ogg_free(look->decodemap);
65
66
10.0k
    memset(look,0,sizeof(*look));
67
10.0k
    _ogg_free(look);
68
10.0k
  }
69
10.0k
}
70
71
15.2k
static int ilog(unsigned int v){
72
15.2k
  int ret=0;
73
33.4k
  while(v){
74
18.2k
    ret++;
75
18.2k
    v>>=1;
76
18.2k
  }
77
15.2k
  return(ret);
78
15.2k
}
79
80
15.7k
static int icount(unsigned int v){
81
15.7k
  int ret=0;
82
40.6k
  while(v){
83
24.9k
    ret+=v&1;
84
24.9k
    v>>=1;
85
24.9k
  }
86
15.7k
  return(ret);
87
15.7k
}
88
89
/* vorbis_info is for range checking */
90
8.42k
vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
91
8.42k
  int j,acc=0;
92
8.42k
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)_ogg_calloc(1,sizeof(*info));
93
8.42k
  codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
94
95
8.42k
  info->begin=oggpack_read(opb,24);
96
8.42k
  info->end=oggpack_read(opb,24);
97
8.42k
  info->grouping=oggpack_read(opb,24)+1;
98
8.42k
  info->partitions=oggpack_read(opb,6)+1;
99
8.42k
  info->groupbook=oggpack_read(opb,8);
100
101
  /* check for premature EOP */
102
8.42k
  if(info->groupbook<0)goto errout;
103
104
24.1k
  for(j=0;j<info->partitions;j++){
105
15.7k
    int cascade=oggpack_read(opb,3);
106
15.7k
    int cflag=oggpack_read(opb,1);
107
15.7k
    if(cflag<0) goto errout;
108
15.7k
    if(cflag){
109
3.39k
      int c=oggpack_read(opb,5);
110
3.39k
      if(c<0) goto errout;
111
3.39k
      cascade|=(c<<3);
112
3.39k
    }
113
15.7k
    info->secondstages[j]=cascade;
114
115
15.7k
    acc+=icount(cascade);
116
15.7k
  }
117
18.0k
  for(j=0;j<acc;j++){
118
9.64k
    int book=oggpack_read(opb,8);
119
9.64k
    if(book<0) goto errout;
120
9.62k
    info->booklist[j]=book;
121
9.62k
  }
122
123
8.37k
  if(info->groupbook>=ci->books)goto errout;
124
17.3k
  for(j=0;j<acc;j++){
125
9.04k
    if(info->booklist[j]>=ci->books)goto errout;
126
9.02k
    if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
127
9.02k
  }
128
129
  /* verify the phrasebook is not specifying an impossible or
130
     inconsistent partitioning scheme. */
131
  /* modify the phrasebook ranging check from r16327; an early beta
132
     encoder had a bug where it used an oversized phrasebook by
133
     accident.  These files should continue to be playable, but don't
134
     allow an exploit */
135
8.33k
  {
136
8.33k
    int entries = ci->book_param[info->groupbook]->entries;
137
8.33k
    int dim = ci->book_param[info->groupbook]->dim;
138
8.33k
    int partvals = 1;
139
8.33k
    if (dim<1) goto errout;
140
70.5M
    while(dim>0){
141
70.5M
      partvals *= info->partitions;
142
70.5M
      if(partvals > entries) goto errout;
143
70.5M
      dim--;
144
70.5M
    }
145
8.31k
    info->partvals = partvals;
146
8.31k
  }
147
148
0
  return(info);
149
107
 errout:
150
107
  res0_free_info(info);
151
107
  return(NULL);
152
8.33k
}
153
154
vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm,
155
10.0k
        vorbis_info_residue *vr){
156
10.0k
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
157
10.0k
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)_ogg_calloc(1,sizeof(*look));
158
10.0k
  codec_setup_info     *ci=(codec_setup_info *)vd->vi->codec_setup;
159
160
10.0k
  int j,k,acc=0;
161
10.0k
  int dim;
162
10.0k
  int maxstage=0;
163
10.0k
  look->info=info;
164
10.0k
  look->map=vm->mapping;
165
166
10.0k
  look->parts=info->partitions;
167
10.0k
  look->fullbooks=ci->fullbooks;
168
10.0k
  look->phrasebook=ci->fullbooks+info->groupbook;
169
10.0k
  dim=look->phrasebook->dim;
170
171
10.0k
  look->partbooks=(codebook ***)_ogg_calloc(look->parts,sizeof(*look->partbooks));
172
173
25.3k
  for(j=0;j<look->parts;j++){
174
15.2k
    int stages=ilog(info->secondstages[j]);
175
15.2k
    if(stages){
176
4.66k
      if(stages>maxstage)maxstage=stages;
177
4.66k
      look->partbooks[j]=(codebook **)_ogg_calloc(stages,sizeof(*look->partbooks[j]));
178
22.8k
      for(k=0;k<stages;k++)
179
18.2k
  if(info->secondstages[j]&(1<<k)){
180
7.16k
    look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
181
#ifdef TRAIN_RES
182
    look->training_data[k][j]=calloc(look->partbooks[j][k]->entries,
183
             sizeof(***look->training_data));
184
#endif
185
7.16k
  }
186
4.66k
    }
187
15.2k
  }
188
189
10.0k
  look->partvals=look->parts;
190
133M
  for(j=1;j<dim;j++)look->partvals*=look->parts;
191
10.0k
  look->stages=maxstage;
192
10.0k
  look->decodemap=(int **)_ogg_malloc(look->partvals*sizeof(*look->decodemap));
193
53.4k
  for(j=0;j<look->partvals;j++){
194
43.4k
    long val=j;
195
43.4k
    long mult=look->partvals/look->parts;
196
43.4k
    look->decodemap[j]=(int *)_ogg_malloc(dim*sizeof(*look->decodemap[j]));
197
133M
    for(k=0;k<dim;k++){
198
133M
      long deco=val/mult;
199
133M
      val-=deco*mult;
200
133M
      mult/=look->parts;
201
133M
      look->decodemap[j][k]=deco;
202
133M
    }
203
43.4k
  }
204
205
10.0k
  return(look);
206
10.0k
}
207
208
209
/* a truncated packet here just means 'stop working'; it's not an error */
210
static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
211
          ogg_int32_t **in,int ch,
212
          long (*decodepart)(codebook *, ogg_int32_t *, 
213
13.9k
           oggpack_buffer *,int,int)){
214
215
13.9k
  long i,j,k,l,s;
216
13.9k
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
217
13.9k
  vorbis_info_residue0 *info=look->info;
218
219
  /* move all this setup out later */
220
13.9k
  int samples_per_partition=info->grouping;
221
13.9k
  int partitions_per_word=look->phrasebook->dim;
222
13.9k
  int max=vb->pcmend>>1;
223
13.9k
  int end=(info->end<max?info->end:max);
224
13.9k
  int n=end-info->begin;
225
226
13.9k
  if(n>0){
227
8.33k
    int partvals=n/samples_per_partition;
228
8.33k
    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
229
8.33k
    int ***partword=(int ***)alloca(ch*sizeof(*partword));
230
    
231
27.7k
    for(j=0;j<ch;j++)
232
19.4k
      partword[j]=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
233
    
234
20.5k
    for(s=0;s<look->stages;s++){
235
      
236
      /* each loop decodes on partition codeword containing 
237
   partitions_pre_word partitions */
238
37.8k
      for(i=0,l=0;i<partvals;l++){
239
25.6k
  if(s==0){
240
    /* fetch the partition word for each channel */
241
30.2k
    for(j=0;j<ch;j++){
242
22.5k
      int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
243
22.5k
      if(temp==-1 || temp>=info->partvals)goto eopbreak;
244
20.6k
      partword[j][l]=look->decodemap[temp];
245
20.6k
      if(partword[j][l]==NULL)goto errout;
246
20.6k
    }
247
9.53k
  }
248
  
249
  /* now we decode residual values for the partitions */
250
357k
  for(k=0;k<partitions_per_word && i<partvals;k++,i++)
251
755k
    for(j=0;j<ch;j++){
252
421k
      long offset=info->begin+i*samples_per_partition;
253
421k
      if(info->secondstages[partword[j][l][k]]&(1<<s)){
254
49.8k
        codebook *stagebook=look->partbooks[partword[j][l][k]][s];
255
49.8k
        if(stagebook){
256
49.8k
    if(decodepart(stagebook,in[j]+offset,&vb->opb,
257
49.8k
            samples_per_partition,-8)==-1)goto eopbreak;
258
49.8k
        }
259
49.8k
      }
260
421k
    }
261
23.7k
      } 
262
16.5k
    }
263
8.33k
  }
264
9.56k
 errout:
265
13.9k
 eopbreak:
266
13.9k
  return(0);
267
9.56k
}
268
269
int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
270
18.3k
     ogg_int32_t **in,int *nonzero,int ch){
271
18.3k
  int i,used=0;
272
1.40M
  for(i=0;i<ch;i++)
273
1.38M
    if(nonzero[i])
274
31.7k
      in[used++]=in[i];
275
18.3k
  if(used)
276
9.52k
    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
277
8.78k
  else
278
8.78k
    return(0);
279
18.3k
}
280
281
int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
282
7.56k
     ogg_int32_t **in,int *nonzero,int ch){
283
7.56k
  int i,used=0;
284
242k
  for(i=0;i<ch;i++)
285
235k
    if(nonzero[i])
286
11.7k
      in[used++]=in[i];
287
7.56k
  if(used)
288
4.39k
    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
289
3.17k
  else
290
3.17k
    return(0);
291
7.56k
}
292
293
/* duplicate code here as speed is somewhat more important */
294
int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
295
22.1k
     ogg_int32_t **in,int *nonzero,int ch){
296
22.1k
  long i,k,l,s;
297
22.1k
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
298
22.1k
  vorbis_info_residue0 *info=look->info;
299
300
  /* move all this setup out later */
301
22.1k
  int samples_per_partition=info->grouping;
302
22.1k
  int partitions_per_word=look->phrasebook->dim;
303
22.1k
  int max=(vb->pcmend*ch)>>1;
304
22.1k
  int end=(info->end<max?info->end:max);
305
22.1k
  int n=end-info->begin;
306
307
22.1k
  if(n>0){
308
    
309
19.4k
    int partvals=n/samples_per_partition;
310
19.4k
    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
311
19.4k
    int **partword=(int **)_vorbis_block_alloc(vb,partwords*sizeof(*partword));
312
19.4k
    int beginoff=info->begin/ch;
313
    
314
283k
    for(i=0;i<ch;i++)if(nonzero[i])break;
315
19.4k
    if(i==ch)return(0); /* no nonzero vectors */
316
    
317
16.0k
    samples_per_partition/=ch;
318
    
319
22.8k
    for(s=0;s<look->stages;s++){
320
33.2k
      for(i=0,l=0;i<partvals;l++){
321
  
322
26.4k
  if(s==0){
323
    /* fetch the partition word */
324
12.4k
    int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
325
12.4k
    if(temp==-1 || temp>=info->partvals)goto eopbreak;
326
9.24k
    partword[l]=look->decodemap[temp];
327
9.24k
    if(partword[l]==NULL)goto errout;
328
9.24k
  }
329
330
  /* now we decode residual values for the partitions */
331
9.84M
  for(k=0;k<partitions_per_word && i<partvals;k++,i++)
332
9.81M
    if(info->secondstages[partword[l][k]]&(1<<s)){
333
4.00M
      codebook *stagebook=look->partbooks[partword[l][k]][s];
334
      
335
4.00M
      if(stagebook){
336
4.00M
        if(vorbis_book_decodevv_add(stagebook,in,
337
4.00M
            i*samples_per_partition+beginoff,ch,
338
4.00M
            &vb->opb,
339
4.00M
            samples_per_partition,-8)==-1)
340
1.21k
    goto eopbreak;
341
4.00M
      }
342
4.00M
    }
343
23.3k
      } 
344
11.2k
    }
345
16.0k
  }
346
14.3k
 errout:
347
18.7k
 eopbreak:
348
18.7k
  return(0);
349
14.3k
}
350
351
352
vorbis_func_residue residue0_exportbundle={
353
  &res0_unpack,
354
  &res0_look,
355
  &res0_free_info,
356
  &res0_free_look,
357
  &res0_inverse
358
};
359
360
vorbis_func_residue residue1_exportbundle={
361
  &res0_unpack,
362
  &res0_look,
363
  &res0_free_info,
364
  &res0_free_look,
365
  &res1_inverse
366
};
367
368
vorbis_func_residue residue2_exportbundle={
369
  &res0_unpack,
370
  &res0_look,
371
  &res0_free_info,
372
  &res0_free_look,
373
  &res2_inverse
374
};