Coverage Report

Created: 2026-07-25 07:52

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