Coverage Report

Created: 2026-08-13 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vorbis/lib/floor1.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 1 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 "codebook.h"
25
#include "misc.h"
26
#include "scales.h"
27
28
#include <stdio.h>
29
30
#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
31
32
typedef struct lsfit_acc{
33
  int x0;
34
  int x1;
35
36
  int xa;
37
  int ya;
38
  int x2a;
39
  int y2a;
40
  int xya;
41
  int an;
42
43
  int xb;
44
  int yb;
45
  int x2b;
46
  int y2b;
47
  int xyb;
48
  int bn;
49
} lsfit_acc;
50
51
/***********************************************/
52
53
9.90k
static void floor1_free_info(vorbis_info_floor *i){
54
9.90k
  vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
55
9.90k
  if(info){
56
9.90k
    memset(info,0,sizeof(*info));
57
9.90k
    _ogg_free(info);
58
9.90k
  }
59
9.90k
}
60
61
9.44k
static void floor1_free_look(vorbis_look_floor *i){
62
9.44k
  vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
63
9.44k
  if(look){
64
    /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
65
            (float)look->phrasebits/look->frames,
66
            (float)look->postbits/look->frames,
67
            (float)(look->postbits+look->phrasebits)/look->frames);*/
68
69
9.44k
    memset(look,0,sizeof(*look));
70
9.44k
    _ogg_free(look);
71
9.44k
  }
72
9.44k
}
73
74
4.12k
static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
75
4.12k
  vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
76
4.12k
  int j,k;
77
4.12k
  int count=0;
78
4.12k
  int rangebits;
79
4.12k
  int maxposit=info->postlist[1];
80
4.12k
  int maxclass=-1;
81
82
  /* save out partitions */
83
4.12k
  oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
84
26.1k
  for(j=0;j<info->partitions;j++){
85
22.0k
    oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
86
22.0k
    if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
87
22.0k
  }
88
89
  /* save out partition classes */
90
18.9k
  for(j=0;j<maxclass+1;j++){
91
14.8k
    oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
92
14.8k
    oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
93
14.8k
    if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
94
56.4k
    for(k=0;k<(1<<info->class_subs[j]);k++)
95
41.6k
      oggpack_write(opb,info->class_subbook[j][k]+1,8);
96
14.8k
  }
97
98
  /* save out the post list */
99
4.12k
  oggpack_write(opb,info->mult-1,2);     /* only 1,2,3,4 legal now */
100
  /* maxposit cannot legally be less than 1; this is encode-side, we
101
     can assume our setup is OK */
102
4.12k
  oggpack_write(opb,ov_ilog(maxposit-1),4);
103
4.12k
  rangebits=ov_ilog(maxposit-1);
104
105
26.1k
  for(j=0,k=0;j<info->partitions;j++){
106
22.0k
    count+=info->class_dim[info->partitionclass[j]];
107
92.4k
    for(;k<count;k++)
108
70.4k
      oggpack_write(opb,info->postlist[k+2],rangebits);
109
22.0k
  }
110
4.12k
}
111
112
386k
static int icomp(const void *a,const void *b){
113
386k
  return(**(int **)a-**(int **)b);
114
386k
}
115
116
5.77k
static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
117
5.77k
  codec_setup_info     *ci=vi->codec_setup;
118
5.77k
  int j,k,count=0,maxclass=-1,rangebits;
119
120
5.77k
  vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
121
  /* read partitions */
122
5.77k
  info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
123
12.5k
  for(j=0;j<info->partitions;j++){
124
6.75k
    info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
125
6.75k
    if(info->partitionclass[j]<0)goto err_out;
126
6.74k
    if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
127
6.74k
  }
128
129
  /* read partition classes */
130
7.96k
  for(j=0;j<maxclass+1;j++){
131
2.23k
    info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
132
2.23k
    info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
133
2.23k
    if(info->class_subs[j]<0)
134
4
      goto err_out;
135
2.23k
    if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
136
2.23k
    if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
137
15
      goto err_out;
138
8.20k
    for(k=0;k<(1<<info->class_subs[j]);k++){
139
6.00k
      info->class_subbook[j][k]=oggpack_read(opb,8)-1;
140
6.00k
      if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
141
19
        goto err_out;
142
6.00k
    }
143
2.22k
  }
144
145
  /* read the post list */
146
5.73k
  info->mult=oggpack_read(opb,2)+1;     /* only 1,2,3,4 legal now */
147
5.73k
  rangebits=oggpack_read(opb,4);
148
5.73k
  if(rangebits<0)goto err_out;
149
150
12.1k
  for(j=0,k=0;j<info->partitions;j++){
151
6.43k
    count+=info->class_dim[info->partitionclass[j]];
152
6.43k
    if(count>VIF_POSIT) goto err_out;
153
24.6k
    for(;k<count;k++){
154
18.1k
      int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
155
18.1k
      if(t<0 || t>=(1<<rangebits))
156
6
        goto err_out;
157
18.1k
    }
158
6.42k
  }
159
5.71k
  info->postlist[0]=0;
160
5.71k
  info->postlist[1]=1<<rangebits;
161
162
  /* don't allow repeated values in post list as they'd result in
163
     zero-length segments */
164
5.71k
  {
165
5.71k
    int *sortpointer[VIF_POSIT+2];
166
35.1k
    for(j=0;j<count+2;j++)sortpointer[j]=info->postlist+j;
167
5.71k
    qsort(sortpointer,count+2,sizeof(*sortpointer),icomp);
168
169
28.9k
    for(j=1;j<count+2;j++)
170
23.2k
      if(*sortpointer[j-1]==*sortpointer[j])goto err_out;
171
5.71k
  }
172
173
5.69k
  return(info);
174
175
78
 err_out:
176
78
  floor1_free_info(info);
177
78
  return(NULL);
178
5.71k
}
179
180
static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
181
9.44k
                                      vorbis_info_floor *in){
182
183
9.44k
  int *sortpointer[VIF_POSIT+2];
184
9.44k
  vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
185
9.44k
  vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
186
9.44k
  int i,j,n=0;
187
188
9.44k
  (void)vd;
189
190
9.44k
  look->vi=info;
191
9.44k
  look->n=info->postlist[1];
192
193
  /* we drop each position value in-between already decoded values,
194
     and use linear interpolation to predict each new value past the
195
     edges.  The positions are read in the order of the position
196
     list... we precompute the bounding positions in the lookup.  Of
197
     course, the neighbors can change (if a position is declined), but
198
     this is an initial mapping */
199
200
37.3k
  for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
201
9.44k
  n+=2;
202
9.44k
  look->posts=n;
203
204
  /* also store a sorted position index */
205
115k
  for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
206
9.44k
  qsort(sortpointer,n,sizeof(*sortpointer),icomp);
207
208
  /* points from sort order back to range number */
209
115k
  for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
210
  /* points from range order to sorted position */
211
115k
  for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
212
  /* we actually need the post values too */
213
115k
  for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
214
215
  /* quantize values to multiplier spec */
216
9.44k
  switch(info->mult){
217
1.52k
  case 1: /* 1024 -> 256 */
218
1.52k
    look->quant_q=256;
219
1.52k
    break;
220
3.40k
  case 2: /* 1024 -> 128 */
221
3.40k
    look->quant_q=128;
222
3.40k
    break;
223
2.63k
  case 3: /* 1024 -> 86 */
224
2.63k
    look->quant_q=86;
225
2.63k
    break;
226
1.87k
  case 4: /* 1024 -> 64 */
227
1.87k
    look->quant_q=64;
228
1.87k
    break;
229
9.44k
  }
230
231
  /* discover our neighbors for decode where we don't use fit flags
232
     (that would push the neighbors outward) */
233
96.4k
  for(i=0;i<n-2;i++){
234
87.0k
    int lo=0;
235
87.0k
    int hi=1;
236
87.0k
    int lx=0;
237
87.0k
    int hx=look->n;
238
87.0k
    int currentx=info->postlist[i+2];
239
1.17M
    for(j=0;j<i+2;j++){
240
1.09M
      int x=info->postlist[j];
241
1.09M
      if(x>lx && x<currentx){
242
132k
        lo=j;
243
132k
        lx=x;
244
132k
      }
245
1.09M
      if(x<hx && x>currentx){
246
122k
        hi=j;
247
122k
        hx=x;
248
122k
      }
249
1.09M
    }
250
87.0k
    look->loneighbor[i]=lo;
251
87.0k
    look->hineighbor[i]=hi;
252
87.0k
  }
253
254
9.44k
  return(look);
255
9.44k
}
256
257
2.30M
static int render_point(int x0,int x1,int y0,int y1,int x){
258
2.30M
  y0&=0x7fff; /* mask off flag */
259
2.30M
  y1&=0x7fff;
260
261
2.30M
  {
262
2.30M
    int dy=y1-y0;
263
2.30M
    int adx=x1-x0;
264
2.30M
    int ady=abs(dy);
265
2.30M
    int err=ady*(x-x0);
266
267
2.30M
    int off=err/adx;
268
2.30M
    if(dy<0)return(y0-off);
269
1.23M
    return(y0+off);
270
2.30M
  }
271
2.30M
}
272
273
44.2M
static int vorbis_dBquant(const float *x){
274
44.2M
  int i= *x*7.3142857f+1023.5f;
275
44.2M
  if(i>1023)return(1023);
276
44.2M
  if(i<0)return(0);
277
43.8M
  return i;
278
44.2M
}
279
280
static const float FLOOR1_fromdB_LOOKUP[256]={
281
  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
282
  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
283
  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
284
  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
285
  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
286
  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
287
  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
288
  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
289
  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
290
  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
291
  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
292
  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
293
  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
294
  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
295
  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
296
  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
297
  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
298
  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
299
  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
300
  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
301
  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
302
  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
303
  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
304
  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
305
  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
306
  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
307
  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
308
  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
309
  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
310
  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
311
  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
312
  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
313
  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
314
  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
315
  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
316
  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
317
  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
318
  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
319
  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
320
  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
321
  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
322
  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
323
  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
324
  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
325
  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
326
  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
327
  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
328
  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
329
  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
330
  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
331
  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
332
  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
333
  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
334
  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
335
  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
336
  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
337
  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
338
  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
339
  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
340
  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
341
  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
342
  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
343
  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
344
  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
345
};
346
347
130k
static void render_line(int n, int x0,int x1,int y0,int y1,float *d){
348
130k
  int dy=y1-y0;
349
130k
  int adx=x1-x0;
350
130k
  int ady=abs(dy);
351
130k
  int base=dy/adx;
352
130k
  int sy=(dy<0?base-1:base+1);
353
130k
  int x=x0;
354
130k
  int y=y0;
355
130k
  int err=0;
356
357
130k
  ady-=abs(base*adx);
358
359
130k
  if(n>x1)n=x1;
360
361
130k
  if(x<n)
362
128k
    d[x]*=FLOOR1_fromdB_LOOKUP[y];
363
364
1.83M
  while(++x<n){
365
1.70M
    err=err+ady;
366
1.70M
    if(err>=adx){
367
422k
      err-=adx;
368
422k
      y+=sy;
369
1.27M
    }else{
370
1.27M
      y+=base;
371
1.27M
    }
372
1.70M
    d[x]*=FLOOR1_fromdB_LOOKUP[y];
373
1.70M
  }
374
130k
}
375
376
648k
static void render_line0(int n, int x0,int x1,int y0,int y1,int *d){
377
648k
  int dy=y1-y0;
378
648k
  int adx=x1-x0;
379
648k
  int ady=abs(dy);
380
648k
  int base=dy/adx;
381
648k
  int sy=(dy<0?base-1:base+1);
382
648k
  int x=x0;
383
648k
  int y=y0;
384
648k
  int err=0;
385
386
648k
  ady-=abs(base*adx);
387
388
648k
  if(n>x1)n=x1;
389
390
648k
  if(x<n)
391
648k
    d[x]=y;
392
393
20.3M
  while(++x<n){
394
19.7M
    err=err+ady;
395
19.7M
    if(err>=adx){
396
3.16M
      err-=adx;
397
3.16M
      y+=sy;
398
16.5M
    }else{
399
16.5M
      y+=base;
400
16.5M
    }
401
19.7M
    d[x]=y;
402
19.7M
  }
403
648k
}
404
405
/* the floor has already been filtered to only include relevant sections */
406
static int accumulate_fit(const float *flr,const float *mdct,
407
                          int x0, int x1,lsfit_acc *a,
408
1.28M
                          int n,vorbis_info_floor1 *info){
409
1.28M
  long i;
410
411
1.28M
  int xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0;
412
413
1.28M
  memset(a,0,sizeof(*a));
414
1.28M
  a->x0=x0;
415
1.28M
  a->x1=x1;
416
1.28M
  if(x1>=n)x1=n-1;
417
418
23.9M
  for(i=x0;i<=x1;i++){
419
22.6M
    int quantized=vorbis_dBquant(flr+i);
420
22.6M
    if(quantized){
421
22.4M
      if(mdct[i]+info->twofitatten>=flr[i]){
422
14.8M
        xa  += i;
423
14.8M
        ya  += quantized;
424
14.8M
        x2a += i*i;
425
14.8M
        y2a += quantized*quantized;
426
14.8M
        xya += i*quantized;
427
14.8M
        na++;
428
14.8M
      }else{
429
7.59M
        xb  += i;
430
7.59M
        yb  += quantized;
431
7.59M
        x2b += i*i;
432
7.59M
        y2b += quantized*quantized;
433
7.59M
        xyb += i*quantized;
434
7.59M
        nb++;
435
7.59M
      }
436
22.4M
    }
437
22.6M
  }
438
439
1.28M
  a->xa=xa;
440
1.28M
  a->ya=ya;
441
1.28M
  a->x2a=x2a;
442
1.28M
  a->y2a=y2a;
443
1.28M
  a->xya=xya;
444
1.28M
  a->an=na;
445
446
1.28M
  a->xb=xb;
447
1.28M
  a->yb=yb;
448
1.28M
  a->x2b=x2b;
449
1.28M
  a->y2b=y2b;
450
1.28M
  a->xyb=xyb;
451
1.28M
  a->bn=nb;
452
453
1.28M
  return(na);
454
1.28M
}
455
456
static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1,
457
1.22M
                    vorbis_info_floor1 *info){
458
1.22M
  double xb=0,yb=0,x2b=0,y2b=0,xyb=0,bn=0;
459
1.22M
  int i;
460
1.22M
  int x0=a[0].x0;
461
1.22M
  int x1=a[fits-1].x1;
462
463
5.88M
  for(i=0;i<fits;i++){
464
4.65M
    double weight = (a[i].bn+a[i].an)*info->twofitweight/(a[i].an+1)+1.;
465
466
4.65M
    xb+=a[i].xb + a[i].xa * weight;
467
4.65M
    yb+=a[i].yb + a[i].ya * weight;
468
4.65M
    x2b+=a[i].x2b + a[i].x2a * weight;
469
4.65M
    y2b+=a[i].y2b + a[i].y2a * weight;
470
4.65M
    xyb+=a[i].xyb + a[i].xya * weight;
471
4.65M
    bn+=a[i].bn + a[i].an * weight;
472
4.65M
  }
473
474
1.22M
  if(*y0>=0){
475
0
    xb+=   x0;
476
0
    yb+=  *y0;
477
0
    x2b+=  x0 *  x0;
478
0
    y2b+= *y0 * *y0;
479
0
    xyb+= *y0 *  x0;
480
0
    bn++;
481
0
  }
482
483
1.22M
  if(*y1>=0){
484
0
    xb+=   x1;
485
0
    yb+=  *y1;
486
0
    x2b+=  x1 *  x1;
487
0
    y2b+= *y1 * *y1;
488
0
    xyb+= *y1 *  x1;
489
0
    bn++;
490
0
  }
491
492
1.22M
  {
493
1.22M
    double denom=(bn*x2b-xb*xb);
494
495
1.22M
    if(denom>0.){
496
1.22M
      double a=(yb*x2b-xyb*xb)/denom;
497
1.22M
      double b=(bn*xyb-xb*yb)/denom;
498
1.22M
      *y0=rint(a+b*x0);
499
1.22M
      *y1=rint(a+b*x1);
500
501
      /* limit to our range! */
502
1.22M
      if(*y0>1023)*y0=1023;
503
1.22M
      if(*y1>1023)*y1=1023;
504
1.22M
      if(*y0<0)*y0=0;
505
1.22M
      if(*y1<0)*y1=0;
506
507
1.22M
      return 0;
508
1.22M
    }else{
509
3.41k
      *y0=0;
510
3.41k
      *y1=0;
511
3.41k
      return 1;
512
3.41k
    }
513
1.22M
  }
514
1.22M
}
515
516
static int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
517
                         const float *mdct,
518
874k
                         vorbis_info_floor1 *info){
519
874k
  int dy=y1-y0;
520
874k
  int adx=x1-x0;
521
874k
  int ady=abs(dy);
522
874k
  int base=dy/adx;
523
874k
  int sy=(dy<0?base-1:base+1);
524
874k
  int x=x0;
525
874k
  int y=y0;
526
874k
  int err=0;
527
874k
  int val=vorbis_dBquant(mask+x);
528
874k
  int mse=0;
529
874k
  int n=0;
530
531
874k
  ady-=abs(base*adx);
532
533
874k
  mse=(y-val);
534
874k
  mse*=mse;
535
874k
  n++;
536
874k
  if(mdct[x]+info->twofitatten>=mask[x]){
537
821k
    if(y+info->maxover<val)return(1);
538
711k
    if(y-info->maxunder>val)return(1);
539
711k
  }
540
541
21.1M
  while(++x<x1){
542
20.7M
    err=err+ady;
543
20.7M
    if(err>=adx){
544
5.94M
      err-=adx;
545
5.94M
      y+=sy;
546
14.8M
    }else{
547
14.8M
      y+=base;
548
14.8M
    }
549
550
20.7M
    val=vorbis_dBquant(mask+x);
551
20.7M
    mse+=((y-val)*(y-val));
552
20.7M
    n++;
553
20.7M
    if(mdct[x]+info->twofitatten>=mask[x]){
554
14.2M
      if(val){
555
14.0M
        if(y+info->maxover<val)return(1);
556
14.0M
        if(y-info->maxunder>val)return(1);
557
14.0M
      }
558
14.2M
    }
559
20.7M
  }
560
561
349k
  if(info->maxover*info->maxover/n>info->maxerr)return(0);
562
228k
  if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
563
228k
  if(mse/n>info->maxerr)return(1);
564
191k
  return(0);
565
228k
}
566
567
3.07M
static int post_Y(int *A,int *B,int pos){
568
3.07M
  if(A[pos]<0)
569
566k
    return B[pos];
570
2.51M
  if(B[pos]<0)
571
0
    return A[pos];
572
573
2.51M
  return (A[pos]+B[pos])>>1;
574
2.51M
}
575
576
int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
577
                          const float *logmdct,   /* in */
578
105k
                          const float *logmask){
579
105k
  long i,j;
580
105k
  vorbis_info_floor1 *info=look->vi;
581
105k
  long n=look->n;
582
105k
  long posts=look->posts;
583
105k
  long nonzero=0;
584
105k
  lsfit_acc fits[VIF_POSIT+1];
585
105k
  int fit_valueA[VIF_POSIT+2]; /* index by range list position */
586
105k
  int fit_valueB[VIF_POSIT+2]; /* index by range list position */
587
588
105k
  int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
589
105k
  int hineighbor[VIF_POSIT+2];
590
105k
  int *output=NULL;
591
105k
  int memo[VIF_POSIT+2];
592
593
1.50M
  for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
594
1.50M
  for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
595
1.50M
  for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
596
1.50M
  for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
597
1.50M
  for(i=0;i<posts;i++)memo[i]=-1;      /* no neighbor yet */
598
599
  /* quantize the relevant floor points and collect them into line fit
600
     structures (one per minimal division) at the same time */
601
105k
  if(posts==0){
602
0
    nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
603
105k
  }else{
604
1.39M
    for(i=0;i<posts-1;i++)
605
1.28M
      nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
606
1.28M
                              look->sorted_index[i+1],fits+i,
607
1.28M
                              n,info);
608
105k
  }
609
610
105k
  if(nonzero){
611
    /* start by fitting the implicit base case.... */
612
101k
    int y0=-200;
613
101k
    int y1=-200;
614
101k
    fit_line(fits,posts-1,&y0,&y1,info);
615
616
101k
    fit_valueA[0]=y0;
617
101k
    fit_valueB[0]=y0;
618
101k
    fit_valueB[1]=y1;
619
101k
    fit_valueA[1]=y1;
620
621
    /* Non degenerate case */
622
    /* start progressive splitting.  This is a greedy, non-optimal
623
       algorithm, but simple and close enough to the best
624
       answer. */
625
1.22M
    for(i=2;i<posts;i++){
626
1.12M
      int sortpos=look->reverse_index[i];
627
1.12M
      int ln=loneighbor[sortpos];
628
1.12M
      int hn=hineighbor[sortpos];
629
630
      /* eliminate repeat searches of a particular range with a memo */
631
1.12M
      if(memo[ln]!=hn){
632
        /* haven't performed this error search yet */
633
874k
        int lsortpos=look->reverse_index[ln];
634
874k
        int hsortpos=look->reverse_index[hn];
635
874k
        memo[ln]=hn;
636
637
874k
        {
638
          /* A note: we want to bound/minimize *local*, not global, error */
639
874k
          int lx=info->postlist[ln];
640
874k
          int hx=info->postlist[hn];
641
874k
          int ly=post_Y(fit_valueA,fit_valueB,ln);
642
874k
          int hy=post_Y(fit_valueA,fit_valueB,hn);
643
644
874k
          if(ly==-1 || hy==-1){
645
0
            exit(1);
646
0
          }
647
648
874k
          if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
649
            /* outside error bounds/begin search area.  Split it. */
650
561k
            int ly0=-200;
651
561k
            int ly1=-200;
652
561k
            int hy0=-200;
653
561k
            int hy1=-200;
654
561k
            int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1,info);
655
561k
            int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1,info);
656
657
561k
            if(ret0){
658
2.60k
              ly0=ly;
659
2.60k
              ly1=hy0;
660
2.60k
            }
661
561k
            if(ret1){
662
812
              hy0=ly1;
663
812
              hy1=hy;
664
812
            }
665
666
561k
            if(ret0 && ret1){
667
491
              fit_valueA[i]=-200;
668
491
              fit_valueB[i]=-200;
669
561k
            }else{
670
              /* store new edge values */
671
561k
              fit_valueB[ln]=ly0;
672
561k
              if(ln==0)fit_valueA[ln]=ly0;
673
561k
              fit_valueA[i]=ly1;
674
561k
              fit_valueB[i]=hy0;
675
561k
              fit_valueA[hn]=hy1;
676
561k
              if(hn==1)fit_valueB[hn]=hy1;
677
678
561k
              if(ly1>=0 || hy0>=0){
679
                /* store new neighbor values */
680
2.08M
                for(j=sortpos-1;j>=0;j--)
681
1.89M
                  if(hineighbor[j]==hn)
682
1.52M
                    hineighbor[j]=i;
683
368k
                  else
684
368k
                    break;
685
2.46M
                for(j=sortpos+1;j<posts;j++)
686
2.23M
                  if(loneighbor[j]==ln)
687
1.90M
                    loneighbor[j]=i;
688
332k
                  else
689
332k
                    break;
690
561k
              }
691
561k
            }
692
561k
          }else{
693
312k
            fit_valueA[i]=-200;
694
312k
            fit_valueB[i]=-200;
695
312k
          }
696
874k
        }
697
874k
      }
698
1.12M
    }
699
700
101k
    output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
701
702
101k
    output[0]=post_Y(fit_valueA,fit_valueB,0);
703
101k
    output[1]=post_Y(fit_valueA,fit_valueB,1);
704
705
    /* fill in posts marked as not using a fit; we will zero
706
       back out to 'unused' when encoding them so long as curve
707
       interpolation doesn't force them into use */
708
1.22M
    for(i=2;i<posts;i++){
709
1.12M
      int ln=look->loneighbor[i-2];
710
1.12M
      int hn=look->hineighbor[i-2];
711
1.12M
      int x0=info->postlist[ln];
712
1.12M
      int x1=info->postlist[hn];
713
1.12M
      int y0=output[ln];
714
1.12M
      int y1=output[hn];
715
716
1.12M
      int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
717
1.12M
      int vx=post_Y(fit_valueA,fit_valueB,i);
718
719
1.12M
      if(vx>=0 && predicted!=vx){
720
557k
        output[i]=vx;
721
569k
      }else{
722
569k
        output[i]= predicted|0x8000;
723
569k
      }
724
1.12M
    }
725
101k
  }
726
727
105k
  return(output);
728
729
105k
}
730
731
int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
732
                          int *A,int *B,
733
0
                          int del){
734
735
0
  long i;
736
0
  long posts=look->posts;
737
0
  int *output=NULL;
738
739
0
  if(A && B){
740
0
    output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
741
742
    /* overly simpleminded--- look again post 1.2 */
743
0
    for(i=0;i<posts;i++){
744
0
      output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
745
0
      if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
746
0
    }
747
0
  }
748
749
0
  return(output);
750
0
}
751
752
753
int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
754
                  vorbis_look_floor1 *look,
755
105k
                  int *post,int *ilogmask){
756
757
105k
  long i,j;
758
105k
  vorbis_info_floor1 *info=look->vi;
759
105k
  long posts=look->posts;
760
105k
  codec_setup_info *ci=vb->vd->vi->codec_setup;
761
105k
  int out[VIF_POSIT+2];
762
105k
  static_codebook **sbooks=ci->book_param;
763
105k
  codebook *books=ci->fullbooks;
764
765
  /* quantize values to multiplier spec */
766
105k
  if(post){
767
1.43M
    for(i=0;i<posts;i++){
768
1.33M
      int val=post[i]&0x7fff;
769
1.33M
      switch(info->mult){
770
0
      case 1: /* 1024 -> 256 */
771
0
        val>>=2;
772
0
        break;
773
988k
      case 2: /* 1024 -> 128 */
774
988k
        val>>=3;
775
988k
        break;
776
0
      case 3: /* 1024 -> 86 */
777
0
        val/=12;
778
0
        break;
779
342k
      case 4: /* 1024 -> 64 */
780
342k
        val>>=4;
781
342k
        break;
782
1.33M
      }
783
1.33M
      post[i]=val | (post[i]&0x8000);
784
1.33M
    }
785
786
101k
    out[0]=post[0];
787
101k
    out[1]=post[1];
788
789
    /* find prediction values for each post and subtract them */
790
1.22M
    for(i=2;i<posts;i++){
791
1.12M
      int ln=look->loneighbor[i-2];
792
1.12M
      int hn=look->hineighbor[i-2];
793
1.12M
      int x0=info->postlist[ln];
794
1.12M
      int x1=info->postlist[hn];
795
1.12M
      int y0=post[ln];
796
1.12M
      int y1=post[hn];
797
798
1.12M
      int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
799
800
1.12M
      if((post[i]&0x8000) || (predicted==post[i])){
801
597k
        post[i]=predicted|0x8000; /* in case there was roundoff jitter
802
                                     in interpolation */
803
597k
        out[i]=0;
804
597k
      }else{
805
530k
        int headroom=(look->quant_q-predicted<predicted?
806
422k
                      look->quant_q-predicted:predicted);
807
808
530k
        int val=post[i]-predicted;
809
810
        /* at this point the 'deviation' value is in the range +/- max
811
           range, but the real, unique range can always be mapped to
812
           only [0-maxrange).  So we want to wrap the deviation into
813
           this limited range, but do it in the way that least screws
814
           an essentially gaussian probability distribution. */
815
816
530k
        if(val<0)
817
358k
          if(val<-headroom)
818
16.5k
            val=headroom-val-1;
819
341k
          else
820
341k
            val=-1-(val*2);
821
172k
        else
822
172k
          if(val>=headroom)
823
990
            val= val+headroom;
824
171k
          else
825
171k
            val<<=1;
826
827
530k
        out[i]=val;
828
530k
        post[ln]&=0x7fff;
829
530k
        post[hn]&=0x7fff;
830
530k
      }
831
1.12M
    }
832
833
    /* we have everything we need. pack it out */
834
    /* mark nontrivial floor */
835
101k
    oggpack_write(opb,1,1);
836
837
    /* beginning/end post */
838
101k
    look->frames++;
839
101k
    look->postbits+=ov_ilog(look->quant_q-1)*2;
840
101k
    oggpack_write(opb,out[0],ov_ilog(look->quant_q-1));
841
101k
    oggpack_write(opb,out[1],ov_ilog(look->quant_q-1));
842
843
844
    /* partition by partition */
845
471k
    for(i=0,j=2;i<info->partitions;i++){
846
369k
      int class=info->partitionclass[i];
847
369k
      int cdim=info->class_dim[class];
848
369k
      int csubbits=info->class_subs[class];
849
369k
      int csub=1<<csubbits;
850
369k
      int bookas[8]={0,0,0,0,0,0,0,0};
851
369k
      int cval=0;
852
369k
      int cshift=0;
853
369k
      int k,l;
854
855
      /* generate the partition's first stage cascade value */
856
369k
      if(csubbits){
857
319k
        int maxval[8]={0,0,0,0,0,0,0,0}; /* gcc's static analysis
858
                                            issues a warning without
859
                                            initialization */
860
1.39M
        for(k=0;k<csub;k++){
861
1.07M
          int booknum=info->class_subbook[class][k];
862
1.07M
          if(booknum<0){
863
177k
            maxval[k]=1;
864
895k
          }else{
865
895k
            maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
866
895k
          }
867
1.07M
        }
868
1.34M
        for(k=0;k<cdim;k++){
869
1.41M
          for(l=0;l<csub;l++){
870
1.41M
            int val=out[j+k];
871
1.41M
            if(val<maxval[l]){
872
1.02M
              bookas[k]=l;
873
1.02M
              break;
874
1.02M
            }
875
1.41M
          }
876
1.02M
          cval|= bookas[k]<<cshift;
877
1.02M
          cshift+=csubbits;
878
1.02M
        }
879
        /* write it */
880
319k
        look->phrasebits+=
881
319k
          vorbis_book_encode(books+info->class_book[class],cval,opb);
882
883
#ifdef TRAIN_FLOOR1
884
        {
885
          FILE *of;
886
          char buffer[80];
887
          sprintf(buffer,"line_%dx%ld_class%d.vqd",
888
                  vb->pcmend/2,posts-2,class);
889
          of=fopen(buffer,"a");
890
          fprintf(of,"%d\n",cval);
891
          fclose(of);
892
        }
893
#endif
894
319k
      }
895
896
      /* write post values */
897
1.49M
      for(k=0;k<cdim;k++){
898
1.12M
        int book=info->class_subbook[class][bookas[k]];
899
1.12M
        if(book>=0){
900
          /* hack to allow training with 'bad' books */
901
712k
          if(out[j+k]<(books+book)->entries)
902
712k
            look->postbits+=vorbis_book_encode(books+book,
903
712k
                                               out[j+k],opb);
904
          /*else
905
            fprintf(stderr,"+!");*/
906
907
#ifdef TRAIN_FLOOR1
908
          {
909
            FILE *of;
910
            char buffer[80];
911
            sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
912
                    vb->pcmend/2,posts-2,class,bookas[k]);
913
            of=fopen(buffer,"a");
914
            fprintf(of,"%d\n",out[j+k]);
915
            fclose(of);
916
          }
917
#endif
918
712k
        }
919
1.12M
      }
920
369k
      j+=cdim;
921
369k
    }
922
923
101k
    {
924
      /* generate quantized floor equivalent to what we'd unpack in decode */
925
      /* render the lines */
926
101k
      int hx=0;
927
101k
      int lx=0;
928
101k
      int ly=post[0]*info->mult;
929
101k
      int n=ci->blocksizes[vb->W]/2;
930
931
1.33M
      for(j=1;j<look->posts;j++){
932
1.22M
        int current=look->forward_index[j];
933
1.22M
        int hy=post[current]&0x7fff;
934
1.22M
        if(hy==post[current]){
935
936
648k
          hy*=info->mult;
937
648k
          hx=info->postlist[current];
938
939
648k
          render_line0(n,lx,hx,ly,hy,ilogmask);
940
941
648k
          lx=hx;
942
648k
          ly=hy;
943
648k
        }
944
1.22M
      }
945
101k
      for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
946
101k
      return(1);
947
101k
    }
948
101k
  }else{
949
4.29k
    oggpack_write(opb,0,1);
950
4.29k
    memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
951
4.29k
    return(0);
952
4.29k
  }
953
105k
}
954
955
2.10M
static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
956
2.10M
  vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
957
2.10M
  vorbis_info_floor1 *info=look->vi;
958
2.10M
  codec_setup_info   *ci=vb->vd->vi->codec_setup;
959
960
2.10M
  int i,j,k;
961
2.10M
  dec_codebook *books=ci->decbooks;
962
963
  /* unpack wrapped/predicted values from stream */
964
2.10M
  if(oggpack_read(&vb->opb,1)==1){
965
124k
    int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
966
967
124k
    fit_value[0]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1));
968
124k
    fit_value[1]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1));
969
970
    /* partition by partition */
971
152k
    for(i=0,j=2;i<info->partitions;i++){
972
28.5k
      int class=info->partitionclass[i];
973
28.5k
      int cdim=info->class_dim[class];
974
28.5k
      int csubbits=info->class_subs[class];
975
28.5k
      int csub=1<<csubbits;
976
28.5k
      int cval=0;
977
978
      /* decode the partition's first stage cascade value */
979
28.5k
      if(csubbits){
980
8.77k
        cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
981
982
8.77k
        if(cval==-1)goto eop;
983
8.77k
      }
984
985
78.1k
      for(k=0;k<cdim;k++){
986
50.1k
        int book=info->class_subbook[class][cval&(csub-1)];
987
50.1k
        cval>>=csubbits;
988
50.1k
        if(book>=0){
989
21.0k
          if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
990
444
            goto eop;
991
29.0k
        }else{
992
29.0k
          fit_value[j+k]=0;
993
29.0k
        }
994
50.1k
      }
995
28.0k
      j+=cdim;
996
28.0k
    }
997
998
    /* unwrap positive values and reconsitute via linear interpolation */
999
173k
    for(i=2;i<look->posts;i++){
1000
49.5k
      int predicted=render_point(info->postlist[look->loneighbor[i-2]],
1001
49.5k
                                 info->postlist[look->hineighbor[i-2]],
1002
49.5k
                                 fit_value[look->loneighbor[i-2]],
1003
49.5k
                                 fit_value[look->hineighbor[i-2]],
1004
49.5k
                                 info->postlist[i]);
1005
49.5k
      int hiroom=look->quant_q-predicted;
1006
49.5k
      int loroom=predicted;
1007
49.5k
      int room=(hiroom<loroom?hiroom:loroom)<<1;
1008
49.5k
      int val=fit_value[i];
1009
1010
49.5k
      if(val){
1011
17.8k
        if(val>=room){
1012
2.29k
          if(hiroom>loroom){
1013
1.25k
            val = val-loroom;
1014
1.25k
          }else{
1015
1.04k
            val = -1-(val-hiroom);
1016
1.04k
          }
1017
15.5k
        }else{
1018
15.5k
          if(val&1){
1019
10.7k
            val= -((val+1)>>1);
1020
10.7k
          }else{
1021
4.72k
            val>>=1;
1022
4.72k
          }
1023
15.5k
        }
1024
1025
17.8k
        fit_value[i]=(val+predicted)&0x7fff;
1026
17.8k
        fit_value[look->loneighbor[i-2]]&=0x7fff;
1027
17.8k
        fit_value[look->hineighbor[i-2]]&=0x7fff;
1028
1029
31.7k
      }else{
1030
31.7k
        fit_value[i]=predicted|0x8000;
1031
31.7k
      }
1032
1033
49.5k
    }
1034
1035
124k
    return(fit_value);
1036
124k
  }
1037
1.98M
 eop:
1038
1.98M
  return(NULL);
1039
2.10M
}
1040
1041
static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
1042
2.10M
                          float *out){
1043
2.10M
  vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
1044
2.10M
  vorbis_info_floor1 *info=look->vi;
1045
1046
2.10M
  codec_setup_info   *ci=vb->vd->vi->codec_setup;
1047
2.10M
  int                  n=ci->blocksizes[vb->W]/2;
1048
2.10M
  int j;
1049
1050
2.10M
  if(memo){
1051
    /* render the lines */
1052
124k
    int *fit_value=(int *)memo;
1053
124k
    int hx=0;
1054
124k
    int lx=0;
1055
124k
    int ly=fit_value[0]*info->mult;
1056
    /* guard lookup against out-of-range values */
1057
124k
    ly=(ly<0?0:ly>255?255:ly);
1058
1059
298k
    for(j=1;j<look->posts;j++){
1060
173k
      int current=look->forward_index[j];
1061
173k
      int hy=fit_value[current]&0x7fff;
1062
173k
      if(hy==fit_value[current]){
1063
1064
130k
        hx=info->postlist[current];
1065
130k
        hy*=info->mult;
1066
        /* guard lookup against out-of-range values */
1067
130k
        hy=(hy<0?0:hy>255?255:hy);
1068
1069
130k
        render_line(n,lx,hx,ly,hy,out);
1070
1071
130k
        lx=hx;
1072
130k
        ly=hy;
1073
130k
      }
1074
173k
    }
1075
84.1M
    for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
1076
124k
    return(1);
1077
124k
  }
1078
1.98M
  memset(out,0,sizeof(*out)*n);
1079
1.98M
  return(0);
1080
2.10M
}
1081
1082
/* export hooks */
1083
const vorbis_func_floor floor1_exportbundle={
1084
  &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
1085
  &floor1_free_look,&floor1_inverse1,&floor1_inverse2
1086
};