Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vorbis/lib/floor0.c
Line
Count
Source
1
/********************************************************************
2
 *                                                                  *
3
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7
 *                                                                  *
8
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015             *
9
 * by the Xiph.Org Foundation https://xiph.org/                     *
10
 *                                                                  *
11
 ********************************************************************
12
13
 function: floor backend 0 implementation
14
15
 ********************************************************************/
16
17
#include <stdlib.h>
18
#include <string.h>
19
#include <math.h>
20
#include <ogg/ogg.h>
21
#include "vorbis/codec.h"
22
#include "codec_internal.h"
23
#include "registry.h"
24
#include "lpc.h"
25
#include "lsp.h"
26
#include "codebook.h"
27
#include "scales.h"
28
#include "misc.h"
29
#include "os.h"
30
31
#include "misc.h"
32
#include <stdio.h>
33
34
typedef struct {
35
  int ln;
36
  int  m;
37
  int **linearmap;
38
  int  n[2];
39
40
  vorbis_info_floor0 *vi;
41
42
  long bits;
43
  long frames;
44
} vorbis_look_floor0;
45
46
47
/***********************************************/
48
49
213
static void floor0_free_info(vorbis_info_floor *i){
50
213
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
51
213
  if(info){
52
213
    memset(info,0,sizeof(*info));
53
213
    _ogg_free(info);
54
213
  }
55
213
}
56
57
146
static void floor0_free_look(vorbis_look_floor *i){
58
146
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
59
146
  if(look){
60
61
146
    if(look->linearmap){
62
63
146
      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
64
146
      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
65
66
146
      _ogg_free(look->linearmap);
67
146
    }
68
146
    memset(look,0,sizeof(*look));
69
146
    _ogg_free(look);
70
146
  }
71
146
}
72
73
213
static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
74
213
  codec_setup_info     *ci=vi->codec_setup;
75
213
  int j;
76
77
213
  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
78
213
  info->order=oggpack_read(opb,8);
79
213
  info->rate=oggpack_read(opb,16);
80
213
  info->barkmap=oggpack_read(opb,16);
81
213
  info->ampbits=oggpack_read(opb,6);
82
213
  info->ampdB=oggpack_read(opb,8);
83
213
  info->numbooks=oggpack_read(opb,4)+1;
84
85
213
  if(info->order<1)goto err_out;
86
204
  if(info->rate<1)goto err_out;
87
203
  if(info->barkmap<1)goto err_out;
88
200
  if(info->numbooks<1)goto err_out;
89
90
1.65k
  for(j=0;j<info->numbooks;j++){
91
1.47k
    info->books[j]=oggpack_read(opb,8);
92
1.47k
    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
93
1.46k
    if(ci->decbooks[info->books[j]].maptype==0)goto err_out;
94
1.45k
    if(ci->decbooks[info->books[j]].dim<1)goto err_out;
95
1.45k
  }
96
176
  return(info);
97
98
37
 err_out:
99
37
  floor0_free_info(info);
100
37
  return(NULL);
101
197
}
102
103
/* initialize Bark scale and normalization lookups.  We could do this
104
   with static tables, but Vorbis allows a number of possible
105
   combinations, so it's best to do it computationally.
106
107
   The below is authoritative in terms of defining scale mapping.
108
   Note that the scale depends on the sampling rate as well as the
109
   linear block and mapping sizes */
110
111
static void floor0_map_lazy_init(vorbis_block      *vb,
112
                                 vorbis_info_floor *infoX,
113
232k
                                 vorbis_look_floor0 *look){
114
232k
  if(!look->linearmap[vb->W]){
115
146
    vorbis_dsp_state   *vd=vb->vd;
116
146
    vorbis_info        *vi=vd->vi;
117
146
    codec_setup_info   *ci=vi->codec_setup;
118
146
    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
119
146
    int W=vb->W;
120
146
    int n=ci->blocksizes[W]/2,j;
121
122
    /* we choose a scaling constant so that:
123
       floor(bark(rate/2-1)*C)=mapped-1
124
     floor(bark(rate/2)*C)=mapped */
125
146
    float scale=look->ln/toBARK(info->rate/2.f);
126
127
    /* the mapping from a linear scale to a smaller bark scale is
128
       straightforward.  We do *not* make sure that the linear mapping
129
       does not skip bark-scale bins; the decoder simply skips them and
130
       the encoder may do what it wishes in filling them.  They're
131
       necessary in some mapping combinations to keep the scale spacing
132
       accurate */
133
146
    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
134
85.8k
    for(j=0;j<n;j++){
135
85.6k
      int val=floor( toBARK((info->rate/2.f)/n*j)
136
85.6k
                     *scale); /* bark numbers represent band edges */
137
85.6k
      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
138
85.6k
      look->linearmap[W][j]=val;
139
85.6k
    }
140
146
    look->linearmap[W][j]=-1;
141
146
    look->n[W]=n;
142
146
  }
143
232k
}
144
145
static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
146
146
                                      vorbis_info_floor *i){
147
146
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
148
146
  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
149
150
146
  (void)vd;
151
152
146
  look->m=info->order;
153
146
  look->ln=info->barkmap;
154
146
  look->vi=info;
155
156
146
  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
157
158
146
  return look;
159
146
}
160
161
232k
static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
162
232k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
163
232k
  vorbis_info_floor0 *info=look->vi;
164
232k
  int j,k;
165
166
232k
  int ampraw=oggpack_read(&vb->opb,info->ampbits);
167
232k
  if(ampraw>0){ /* also handles the -1 out of data case */
168
42.4k
    long maxval=(1<<info->ampbits)-1;
169
42.4k
    float amp=(float)ampraw/maxval*info->ampdB;
170
42.4k
    int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
171
172
42.4k
    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
173
17.0k
      codec_setup_info  *ci=vb->vd->vi->codec_setup;
174
17.0k
      dec_codebook *b=ci->decbooks+info->books[booknum];
175
17.0k
      float last=0.f;
176
177
      /* the additional b->dim is a guard against any possible stack
178
         smash; b->dim is provably more than we can overflow the
179
         vector */
180
17.0k
      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
181
182
17.0k
      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
183
151k
      for(j=0;j<look->m;){
184
758k
        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
185
134k
        last=lsp[j-1];
186
134k
      }
187
188
16.7k
      lsp[look->m]=amp;
189
16.7k
      return(lsp);
190
17.0k
    }
191
42.4k
  }
192
216k
 eop:
193
216k
  return(NULL);
194
232k
}
195
196
static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
197
232k
                           void *memo,float *out){
198
232k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
199
232k
  vorbis_info_floor0 *info=look->vi;
200
201
232k
  floor0_map_lazy_init(vb,info,look);
202
203
232k
  if(memo){
204
16.7k
    float *lsp=(float *)memo;
205
16.7k
    float amp=lsp[look->m];
206
207
    /* take the coefficients back to a spectral envelope curve */
208
16.7k
    vorbis_lsp_to_curve(out,
209
16.7k
                        look->linearmap[vb->W],
210
16.7k
                        look->n[vb->W],
211
16.7k
                        look->ln,
212
16.7k
                        lsp,look->m,amp,(float)info->ampdB);
213
16.7k
    return(1);
214
16.7k
  }
215
216k
  memset(out,0,sizeof(*out)*look->n[vb->W]);
216
216k
  return(0);
217
232k
}
218
219
/* export hooks */
220
const vorbis_func_floor floor0_exportbundle={
221
  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
222
  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
223
};