Coverage Report

Created: 2024-07-27 06:05

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