Coverage Report

Created: 2026-02-26 06:36

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
5.24k
static void floor0_free_info(vorbis_info_floor *i){
50
5.24k
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
51
5.24k
  if(info){
52
5.24k
    memset(info,0,sizeof(*info));
53
5.24k
    _ogg_free(info);
54
5.24k
  }
55
5.24k
}
56
57
5.07k
static void floor0_free_look(vorbis_look_floor *i){
58
5.07k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
59
5.07k
  if(look){
60
61
5.07k
    if(look->linearmap){
62
63
5.07k
      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
64
5.07k
      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
65
66
5.07k
      _ogg_free(look->linearmap);
67
5.07k
    }
68
5.07k
    memset(look,0,sizeof(*look));
69
5.07k
    _ogg_free(look);
70
5.07k
  }
71
5.07k
}
72
73
5.24k
static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
74
5.24k
  codec_setup_info     *ci=vi->codec_setup;
75
5.24k
  int j;
76
77
5.24k
  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
78
5.24k
  info->order=oggpack_read(opb,8);
79
5.24k
  info->rate=oggpack_read(opb,16);
80
5.24k
  info->barkmap=oggpack_read(opb,16);
81
5.24k
  info->ampbits=oggpack_read(opb,6);
82
5.24k
  info->ampdB=oggpack_read(opb,8);
83
5.24k
  info->numbooks=oggpack_read(opb,4)+1;
84
85
5.24k
  if(info->order<1)goto err_out;
86
5.23k
  if(info->rate<1)goto err_out;
87
5.23k
  if(info->barkmap<1)goto err_out;
88
5.22k
  if(info->numbooks<1)goto err_out;
89
90
16.6k
  for(j=0;j<info->numbooks;j++){
91
11.4k
    info->books[j]=oggpack_read(opb,8);
92
11.4k
    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
93
11.4k
    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
94
11.4k
    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
95
11.4k
  }
96
5.17k
  return(info);
97
98
69
 err_out:
99
69
  floor0_free_info(info);
100
69
  return(NULL);
101
5.21k
}
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
559k
                                 vorbis_look_floor0 *look){
114
559k
  if(!look->linearmap[vb->W]){
115
4.69k
    vorbis_dsp_state   *vd=vb->vd;
116
4.69k
    vorbis_info        *vi=vd->vi;
117
4.69k
    codec_setup_info   *ci=vi->codec_setup;
118
4.69k
    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
119
4.69k
    int W=vb->W;
120
4.69k
    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
4.69k
    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
4.69k
    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
134
1.70M
    for(j=0;j<n;j++){
135
1.69M
      int val=floor( toBARK((info->rate/2.f)/n*j)
136
1.69M
                     *scale); /* bark numbers represent band edges */
137
1.69M
      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
138
1.69M
      look->linearmap[W][j]=val;
139
1.69M
    }
140
4.69k
    look->linearmap[W][j]=-1;
141
4.69k
    look->n[W]=n;
142
4.69k
  }
143
559k
}
144
145
static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
146
5.07k
                                      vorbis_info_floor *i){
147
5.07k
  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
148
5.07k
  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
149
150
5.07k
  (void)vd;
151
152
5.07k
  look->m=info->order;
153
5.07k
  look->ln=info->barkmap;
154
5.07k
  look->vi=info;
155
156
5.07k
  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
157
158
5.07k
  return look;
159
5.07k
}
160
161
559k
static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
162
559k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
163
559k
  vorbis_info_floor0 *info=look->vi;
164
559k
  int j,k;
165
166
559k
  int ampraw=oggpack_read(&vb->opb,info->ampbits);
167
559k
  if(ampraw>0){ /* also handles the -1 out of data case */
168
55.8k
    long maxval=(1<<info->ampbits)-1;
169
55.8k
    float amp=(float)ampraw/maxval*info->ampdB;
170
55.8k
    int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
171
172
55.8k
    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
173
44.9k
      codec_setup_info  *ci=vb->vd->vi->codec_setup;
174
44.9k
      codebook *b=ci->fullbooks+info->books[booknum];
175
44.9k
      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
44.9k
      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
181
182
44.9k
      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
183
1.05M
      for(j=0;j<look->m;){
184
2.81M
        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
185
1.02M
        last=lsp[j-1];
186
1.02M
      }
187
188
34.6k
      lsp[look->m]=amp;
189
34.6k
      return(lsp);
190
44.9k
    }
191
55.8k
  }
192
525k
 eop:
193
525k
  return(NULL);
194
559k
}
195
196
static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
197
559k
                           void *memo,float *out){
198
559k
  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
199
559k
  vorbis_info_floor0 *info=look->vi;
200
201
559k
  floor0_map_lazy_init(vb,info,look);
202
203
559k
  if(memo){
204
34.6k
    float *lsp=(float *)memo;
205
34.6k
    float amp=lsp[look->m];
206
207
    /* take the coefficients back to a spectral envelope curve */
208
34.6k
    vorbis_lsp_to_curve(out,
209
34.6k
                        look->linearmap[vb->W],
210
34.6k
                        look->n[vb->W],
211
34.6k
                        look->ln,
212
34.6k
                        lsp,look->m,amp,(float)info->ampdB);
213
34.6k
    return(1);
214
34.6k
  }
215
525k
  memset(out,0,sizeof(*out)*look->n[vb->W]);
216
525k
  return(0);
217
559k
}
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
};