Coverage Report

Created: 2026-04-01 07:42

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