Coverage Report

Created: 2026-09-14 08:00

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