xref: /aosp_15_r20/external/tremolo/Tremolo/floor1.c (revision bda690e46497e1f65c5077173b9c548e6e0cd5a1)
1*bda690e4SXin Li /************************************************************************
2*bda690e4SXin Li  * Copyright (C) 2002-2009, Xiph.org Foundation
3*bda690e4SXin Li  * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
4*bda690e4SXin Li  * All rights reserved.
5*bda690e4SXin Li  *
6*bda690e4SXin Li  * Redistribution and use in source and binary forms, with or without
7*bda690e4SXin Li  * modification, are permitted provided that the following conditions
8*bda690e4SXin Li  * are met:
9*bda690e4SXin Li  *
10*bda690e4SXin Li  *     * Redistributions of source code must retain the above copyright
11*bda690e4SXin Li  * notice, this list of conditions and the following disclaimer.
12*bda690e4SXin Li  *     * Redistributions in binary form must reproduce the above
13*bda690e4SXin Li  * copyright notice, this list of conditions and the following disclaimer
14*bda690e4SXin Li  * in the documentation and/or other materials provided with the
15*bda690e4SXin Li  * distribution.
16*bda690e4SXin Li  *     * Neither the names of the Xiph.org Foundation nor Pinknoise
17*bda690e4SXin Li  * Productions Ltd nor the names of its contributors may be used to
18*bda690e4SXin Li  * endorse or promote products derived from this software without
19*bda690e4SXin Li  * specific prior written permission.
20*bda690e4SXin Li  *
21*bda690e4SXin Li  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*bda690e4SXin Li  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*bda690e4SXin Li  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*bda690e4SXin Li  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*bda690e4SXin Li  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*bda690e4SXin Li  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*bda690e4SXin Li  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*bda690e4SXin Li  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*bda690e4SXin Li  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*bda690e4SXin Li  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*bda690e4SXin Li  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*bda690e4SXin Li  ************************************************************************
33*bda690e4SXin Li 
34*bda690e4SXin Li  function: floor backend 1 implementation
35*bda690e4SXin Li 
36*bda690e4SXin Li  ************************************************************************/
37*bda690e4SXin Li 
38*bda690e4SXin Li #include <stdlib.h>
39*bda690e4SXin Li #include <string.h>
40*bda690e4SXin Li #include <math.h>
41*bda690e4SXin Li #include "ogg.h"
42*bda690e4SXin Li #include "ivorbiscodec.h"
43*bda690e4SXin Li #include "codec_internal.h"
44*bda690e4SXin Li #include "codebook.h"
45*bda690e4SXin Li #include "misc.h"
46*bda690e4SXin Li 
47*bda690e4SXin Li extern const ogg_int32_t FLOOR_fromdB_LOOKUP[];
48*bda690e4SXin Li #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
49*bda690e4SXin Li #define VIF_POSIT 63
50*bda690e4SXin Li 
51*bda690e4SXin Li /***********************************************/
52*bda690e4SXin Li 
floor1_free_info(vorbis_info_floor * i)53*bda690e4SXin Li void floor1_free_info(vorbis_info_floor *i){
54*bda690e4SXin Li   vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
55*bda690e4SXin Li   if(info){
56*bda690e4SXin Li     if(info->klass)_ogg_free(info->klass);
57*bda690e4SXin Li     if(info->partitionclass)_ogg_free(info->partitionclass);
58*bda690e4SXin Li     if(info->postlist)_ogg_free(info->postlist);
59*bda690e4SXin Li     if(info->forward_index)_ogg_free(info->forward_index);
60*bda690e4SXin Li     if(info->hineighbor)_ogg_free(info->hineighbor);
61*bda690e4SXin Li     if(info->loneighbor)_ogg_free(info->loneighbor);
62*bda690e4SXin Li     memset(info,0,sizeof(*info));
63*bda690e4SXin Li     _ogg_free(info);
64*bda690e4SXin Li   }
65*bda690e4SXin Li }
66*bda690e4SXin Li 
ilog(unsigned int v)67*bda690e4SXin Li static int ilog(unsigned int v){
68*bda690e4SXin Li   int ret=0;
69*bda690e4SXin Li   while(v){
70*bda690e4SXin Li     ret++;
71*bda690e4SXin Li     v>>=1;
72*bda690e4SXin Li   }
73*bda690e4SXin Li   return(ret);
74*bda690e4SXin Li }
75*bda690e4SXin Li 
mergesort(ogg_uint8_t * index,ogg_uint16_t * vals,ogg_uint16_t n)76*bda690e4SXin Li static void mergesort(ogg_uint8_t *index,ogg_uint16_t *vals,ogg_uint16_t n){
77*bda690e4SXin Li   ogg_uint16_t i,j;
78*bda690e4SXin Li   ogg_uint8_t *temp,*A=index,*B=_ogg_malloc(n*sizeof(*B));
79*bda690e4SXin Li 
80*bda690e4SXin Li   for(i=1;i<n;i<<=1){
81*bda690e4SXin Li     for(j=0;j+i<n;){
82*bda690e4SXin Li       int k1=j;
83*bda690e4SXin Li       int mid=j+i;
84*bda690e4SXin Li       int k2=mid;
85*bda690e4SXin Li       int end=(j+i*2<n?j+i*2:n);
86*bda690e4SXin Li       while(k1<mid && k2<end){
87*bda690e4SXin Li 	if(vals[A[k1]]<vals[A[k2]])
88*bda690e4SXin Li 	  B[j++]=A[k1++];
89*bda690e4SXin Li 	else
90*bda690e4SXin Li 	  B[j++]=A[k2++];
91*bda690e4SXin Li       }
92*bda690e4SXin Li       while(k1<mid) B[j++]=A[k1++];
93*bda690e4SXin Li       while(k2<end) B[j++]=A[k2++];
94*bda690e4SXin Li     }
95*bda690e4SXin Li     for(;j<n;j++)B[j]=A[j];
96*bda690e4SXin Li     temp=A;A=B;B=temp;
97*bda690e4SXin Li   }
98*bda690e4SXin Li 
99*bda690e4SXin Li   if(B==index){
100*bda690e4SXin Li     for(j=0;j<n;j++)B[j]=A[j];
101*bda690e4SXin Li     _ogg_free(A);
102*bda690e4SXin Li   }else
103*bda690e4SXin Li     _ogg_free(B);
104*bda690e4SXin Li }
105*bda690e4SXin Li 
106*bda690e4SXin Li 
floor1_info_unpack(vorbis_info * vi,oggpack_buffer * opb)107*bda690e4SXin Li vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
108*bda690e4SXin Li   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
109*bda690e4SXin Li   int j,k,count=0,maxclass=-1,rangebits;
110*bda690e4SXin Li 
111*bda690e4SXin Li   vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
112*bda690e4SXin Li   /* read partitions */
113*bda690e4SXin Li   info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
114*bda690e4SXin Li   info->partitionclass=
115*bda690e4SXin Li     (ogg_uint8_t *)_ogg_malloc(info->partitions*sizeof(*info->partitionclass));
116*bda690e4SXin Li   for(j=0;j<info->partitions;j++){
117*bda690e4SXin Li     info->partitionclass[j]=(char)oggpack_read(opb,4); /* only 0 to 15 legal */
118*bda690e4SXin Li     if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
119*bda690e4SXin Li   }
120*bda690e4SXin Li 
121*bda690e4SXin Li   /* read partition classes */
122*bda690e4SXin Li   info->klass=
123*bda690e4SXin Li     (floor1class *)_ogg_malloc((maxclass+1)*sizeof(*info->klass));
124*bda690e4SXin Li   for(j=0;j<maxclass+1;j++){
125*bda690e4SXin Li     info->klass[j].class_dim=(char)oggpack_read(opb,3)+1; /* 1 to 8 */
126*bda690e4SXin Li     info->klass[j].class_subs=(char)oggpack_read(opb,2); /* 0,1,2,3 bits */
127*bda690e4SXin Li     if(oggpack_eop(opb)<0) goto err_out;
128*bda690e4SXin Li     if(info->klass[j].class_subs)
129*bda690e4SXin Li       info->klass[j].class_book=(unsigned char)oggpack_read(opb,8);
130*bda690e4SXin Li     else
131*bda690e4SXin Li       info->klass[j].class_book=0;
132*bda690e4SXin Li     if(info->klass[j].class_book>=ci->books)goto err_out;
133*bda690e4SXin Li     for(k=0;k<(1<<info->klass[j].class_subs);k++){
134*bda690e4SXin Li       info->klass[j].class_subbook[k]=(unsigned char)(oggpack_read(opb,8)-1);
135*bda690e4SXin Li       if(info->klass[j].class_subbook[k]>=ci->books &&
136*bda690e4SXin Li 	 info->klass[j].class_subbook[k]!=0xff)goto err_out;
137*bda690e4SXin Li     }
138*bda690e4SXin Li   }
139*bda690e4SXin Li 
140*bda690e4SXin Li   /* read the post list */
141*bda690e4SXin Li   info->mult=oggpack_read(opb,2)+1;     /* only 1,2,3,4 legal now */
142*bda690e4SXin Li   rangebits=oggpack_read(opb,4);
143*bda690e4SXin Li   if(rangebits < 0) goto err_out;
144*bda690e4SXin Li 
145*bda690e4SXin Li   for(j=0,k=0;j<info->partitions;j++)
146*bda690e4SXin Li     count+=info->klass[info->partitionclass[j]].class_dim;
147*bda690e4SXin Li   info->postlist=
148*bda690e4SXin Li     (ogg_uint16_t *)_ogg_malloc((count+2)*sizeof(*info->postlist));
149*bda690e4SXin Li   info->forward_index=
150*bda690e4SXin Li     (ogg_uint8_t *)_ogg_malloc((count+2)*sizeof(*info->forward_index));
151*bda690e4SXin Li   info->loneighbor=
152*bda690e4SXin Li     (ogg_uint8_t *)_ogg_malloc(count*sizeof(*info->loneighbor));
153*bda690e4SXin Li   info->hineighbor=
154*bda690e4SXin Li     (ogg_uint8_t *)_ogg_malloc(count*sizeof(*info->hineighbor));
155*bda690e4SXin Li 
156*bda690e4SXin Li   count=0;
157*bda690e4SXin Li   for(j=0,k=0;j<info->partitions;j++){
158*bda690e4SXin Li     count+=info->klass[info->partitionclass[j]].class_dim;
159*bda690e4SXin Li     for(;k<count;k++){
160*bda690e4SXin Li       int t=info->postlist[k+2]=(ogg_uint16_t)oggpack_read(opb,rangebits);
161*bda690e4SXin Li       if(t>=(1<<rangebits))goto err_out;
162*bda690e4SXin Li     }
163*bda690e4SXin Li   }
164*bda690e4SXin Li   if(oggpack_eop(opb))goto err_out;
165*bda690e4SXin Li   info->postlist[0]=0;
166*bda690e4SXin Li   info->postlist[1]=1<<rangebits;
167*bda690e4SXin Li   info->posts=count+2;
168*bda690e4SXin Li 
169*bda690e4SXin Li   /* also store a sorted position index */
170*bda690e4SXin Li   for(j=0;j<info->posts;j++)info->forward_index[j]=j;
171*bda690e4SXin Li   mergesort(info->forward_index,info->postlist,info->posts);
172*bda690e4SXin Li 
173*bda690e4SXin Li   /* discover our neighbors for decode where we don't use fit flags
174*bda690e4SXin Li      (that would push the neighbors outward) */
175*bda690e4SXin Li   for(j=0;j<info->posts-2;j++){
176*bda690e4SXin Li     int lo=0;
177*bda690e4SXin Li     int hi=1;
178*bda690e4SXin Li     int lx=0;
179*bda690e4SXin Li     int hx=info->postlist[1];
180*bda690e4SXin Li     int currentx=info->postlist[j+2];
181*bda690e4SXin Li     for(k=0;k<j+2;k++){
182*bda690e4SXin Li       int x=info->postlist[k];
183*bda690e4SXin Li       if(x>lx && x<currentx){
184*bda690e4SXin Li 	lo=k;
185*bda690e4SXin Li 	lx=x;
186*bda690e4SXin Li       }
187*bda690e4SXin Li       if(x<hx && x>currentx){
188*bda690e4SXin Li 	hi=k;
189*bda690e4SXin Li 	hx=x;
190*bda690e4SXin Li       }
191*bda690e4SXin Li     }
192*bda690e4SXin Li     info->loneighbor[j]=lo;
193*bda690e4SXin Li     info->hineighbor[j]=hi;
194*bda690e4SXin Li   }
195*bda690e4SXin Li 
196*bda690e4SXin Li   return(info);
197*bda690e4SXin Li 
198*bda690e4SXin Li  err_out:
199*bda690e4SXin Li   floor1_free_info(info);
200*bda690e4SXin Li   return(NULL);
201*bda690e4SXin Li }
202*bda690e4SXin Li 
203*bda690e4SXin Li #ifdef ONLY_C
204*bda690e4SXin Li static
205*bda690e4SXin Li #endif
render_point(int x0,int x1,int y0,int y1,int x)206*bda690e4SXin Li int render_point(int x0,int x1,int y0,int y1,int x){
207*bda690e4SXin Li   y0&=0x7fff; /* mask off flag */
208*bda690e4SXin Li   y1&=0x7fff;
209*bda690e4SXin Li 
210*bda690e4SXin Li   {
211*bda690e4SXin Li     int dy=y1-y0;
212*bda690e4SXin Li     int adx=x1-x0;
213*bda690e4SXin Li     int ady=abs(dy);
214*bda690e4SXin Li     int err=ady*(x-x0);
215*bda690e4SXin Li 
216*bda690e4SXin Li     int off=err/adx;
217*bda690e4SXin Li     if(dy<0)return(y0-off);
218*bda690e4SXin Li     return(y0+off);
219*bda690e4SXin Li   }
220*bda690e4SXin Li }
221*bda690e4SXin Li 
222*bda690e4SXin Li #ifndef ONLY_C
223*bda690e4SXin Li void render_lineARM(int n, ogg_int32_t *d,const ogg_int32_t *floor, int base, int err, int adx, int ady);
224*bda690e4SXin Li #endif
225*bda690e4SXin Li 
render_line(int n,int x0,int x1,int y0,int y1,ogg_int32_t * d)226*bda690e4SXin Li static void render_line(int n,int x0,int x1,int y0,int y1,ogg_int32_t *d){
227*bda690e4SXin Li   int dy;
228*bda690e4SXin Li   int adx;
229*bda690e4SXin Li   int ady;
230*bda690e4SXin Li   int base;
231*bda690e4SXin Li   int err;
232*bda690e4SXin Li   const ogg_int32_t *floor;
233*bda690e4SXin Li 
234*bda690e4SXin Li   if(n>x1)n=x1;
235*bda690e4SXin Li   n -= x0;
236*bda690e4SXin Li   if (n <= 0 || y0 < 0 || y0 > 255 || y1 < 0 || y1 > 255) {
237*bda690e4SXin Li     return;
238*bda690e4SXin Li   }
239*bda690e4SXin Li   dy=y1-y0;
240*bda690e4SXin Li   adx=x1-x0;
241*bda690e4SXin Li   ady=abs(dy);
242*bda690e4SXin Li   base=dy/adx;
243*bda690e4SXin Li   err=adx-1;
244*bda690e4SXin Li   floor=&FLOOR_fromdB_LOOKUP[y0];
245*bda690e4SXin Li   d += x0;
246*bda690e4SXin Li   ady-=abs(base*adx);
247*bda690e4SXin Li 
248*bda690e4SXin Li   /* We should add base each time, and then:
249*bda690e4SXin Li    *   if dy >=0 we occasionally add 1
250*bda690e4SXin Li    *   else         occasionally subtract 1.
251*bda690e4SXin Li    * As an optimisation we say that if dy <0 we make base 1 smaller.
252*bda690e4SXin Li    * Then we need to add 1 occassionally, rather than subtract 1 - but we
253*bda690e4SXin Li    * need to add 1 in all the cases when we wouldn't have done so before.
254*bda690e4SXin Li    * Previously we'd have added 1 (100*ady/adx)% of the time. Now we want
255*bda690e4SXin Li    * to do so (100*(adx-ady)/adx)% of the time.
256*bda690e4SXin Li    */
257*bda690e4SXin Li   if (dy < 0){
258*bda690e4SXin Li     base--;
259*bda690e4SXin Li     ady = adx-ady;
260*bda690e4SXin Li     err = 0;
261*bda690e4SXin Li   }
262*bda690e4SXin Li 
263*bda690e4SXin Li   //if(x<n)
264*bda690e4SXin Li   //  d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
265*bda690e4SXin Li 
266*bda690e4SXin Li #if defined(ONLY_C)
267*bda690e4SXin Li   do{
268*bda690e4SXin Li     *d = MULT31_SHIFT15(*d,*floor);
269*bda690e4SXin Li     d++;
270*bda690e4SXin Li     floor+=base;
271*bda690e4SXin Li     err-=ady;
272*bda690e4SXin Li     if(err<0){
273*bda690e4SXin Li       err+=adx;
274*bda690e4SXin Li       floor+=1;
275*bda690e4SXin Li     }
276*bda690e4SXin Li     n--;
277*bda690e4SXin Li   } while(n>0);
278*bda690e4SXin Li #else
279*bda690e4SXin Li   render_lineARM(n,d,floor,base,err,adx,ady);
280*bda690e4SXin Li #endif
281*bda690e4SXin Li }
282*bda690e4SXin Li 
floor1_memosize(vorbis_info_floor * i)283*bda690e4SXin Li int floor1_memosize(vorbis_info_floor *i){
284*bda690e4SXin Li   vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
285*bda690e4SXin Li   return info->posts;
286*bda690e4SXin Li }
287*bda690e4SXin Li 
288*bda690e4SXin Li static int quant_look[4]={256,128,86,64};
289*bda690e4SXin Li 
floor1_inverse1(vorbis_dsp_state * vd,vorbis_info_floor * in,ogg_int32_t * fit_value)290*bda690e4SXin Li ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in,
291*bda690e4SXin Li 			     ogg_int32_t *fit_value){
292*bda690e4SXin Li   vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
293*bda690e4SXin Li   codec_setup_info   *ci=(codec_setup_info *)vd->vi->codec_setup;
294*bda690e4SXin Li 
295*bda690e4SXin Li   int i,j,k;
296*bda690e4SXin Li   codebook *books=ci->book_param;
297*bda690e4SXin Li   int quant_q=quant_look[info->mult-1];
298*bda690e4SXin Li 
299*bda690e4SXin Li   /* unpack wrapped/predicted values from stream */
300*bda690e4SXin Li   if(oggpack_read(&vd->opb,1)==1){
301*bda690e4SXin Li     fit_value[0]=oggpack_read(&vd->opb,ilog(quant_q-1));
302*bda690e4SXin Li     fit_value[1]=oggpack_read(&vd->opb,ilog(quant_q-1));
303*bda690e4SXin Li 
304*bda690e4SXin Li     /* partition by partition */
305*bda690e4SXin Li     /* partition by partition */
306*bda690e4SXin Li     for(i=0,j=2;i<info->partitions;i++){
307*bda690e4SXin Li       int classv=info->partitionclass[i];
308*bda690e4SXin Li       int cdim=info->klass[classv].class_dim;
309*bda690e4SXin Li       int csubbits=info->klass[classv].class_subs;
310*bda690e4SXin Li       int csub=1<<csubbits;
311*bda690e4SXin Li       int cval=0;
312*bda690e4SXin Li 
313*bda690e4SXin Li       /* decode the partition's first stage cascade value */
314*bda690e4SXin Li       if(csubbits){
315*bda690e4SXin Li 	cval=vorbis_book_decode(books+info->klass[classv].class_book,&vd->opb);
316*bda690e4SXin Li 
317*bda690e4SXin Li 	if(cval==-1)goto eop;
318*bda690e4SXin Li       }
319*bda690e4SXin Li 
320*bda690e4SXin Li       for(k=0;k<cdim;k++){
321*bda690e4SXin Li 	int book=info->klass[classv].class_subbook[cval&(csub-1)];
322*bda690e4SXin Li 	cval>>=csubbits;
323*bda690e4SXin Li 	if(book!=0xff){
324*bda690e4SXin Li 	  if((fit_value[j+k]=vorbis_book_decode(books+book,&vd->opb))==-1)
325*bda690e4SXin Li 	    goto eop;
326*bda690e4SXin Li 	}else{
327*bda690e4SXin Li 	  fit_value[j+k]=0;
328*bda690e4SXin Li 	}
329*bda690e4SXin Li       }
330*bda690e4SXin Li       j+=cdim;
331*bda690e4SXin Li     }
332*bda690e4SXin Li 
333*bda690e4SXin Li     /* unwrap positive values and reconsitute via linear interpolation */
334*bda690e4SXin Li     for(i=2;i<info->posts;i++){
335*bda690e4SXin Li       int predicted=render_point(info->postlist[info->loneighbor[i-2]],
336*bda690e4SXin Li 				 info->postlist[info->hineighbor[i-2]],
337*bda690e4SXin Li 				 fit_value[info->loneighbor[i-2]],
338*bda690e4SXin Li 				 fit_value[info->hineighbor[i-2]],
339*bda690e4SXin Li 				 info->postlist[i]);
340*bda690e4SXin Li       int hiroom=quant_q-predicted;
341*bda690e4SXin Li       int loroom=predicted;
342*bda690e4SXin Li       int room=(hiroom<loroom?hiroom:loroom)<<1;
343*bda690e4SXin Li       int val=fit_value[i];
344*bda690e4SXin Li 
345*bda690e4SXin Li       if(val){
346*bda690e4SXin Li 	if(val>=room){
347*bda690e4SXin Li 	  if(hiroom>loroom){
348*bda690e4SXin Li 	    val = val-loroom;
349*bda690e4SXin Li 	  }else{
350*bda690e4SXin Li 	  val = -1-(val-hiroom);
351*bda690e4SXin Li 	  }
352*bda690e4SXin Li 	}else{
353*bda690e4SXin Li 	  if(val&1){
354*bda690e4SXin Li 	    val= -((val+1)>>1);
355*bda690e4SXin Li 	  }else{
356*bda690e4SXin Li 	    val>>=1;
357*bda690e4SXin Li 	  }
358*bda690e4SXin Li 	}
359*bda690e4SXin Li 
360*bda690e4SXin Li 	fit_value[i]=val+predicted;
361*bda690e4SXin Li 	fit_value[info->loneighbor[i-2]]&=0x7fff;
362*bda690e4SXin Li 	fit_value[info->hineighbor[i-2]]&=0x7fff;
363*bda690e4SXin Li 
364*bda690e4SXin Li       }else{
365*bda690e4SXin Li 	fit_value[i]=predicted|0x8000;
366*bda690e4SXin Li       }
367*bda690e4SXin Li 
368*bda690e4SXin Li     }
369*bda690e4SXin Li 
370*bda690e4SXin Li     return(fit_value);
371*bda690e4SXin Li   }
372*bda690e4SXin Li  eop:
373*bda690e4SXin Li   return(NULL);
374*bda690e4SXin Li }
375*bda690e4SXin Li 
376*bda690e4SXin Li // overflowing calculations not used for indexing
377*bda690e4SXin Li __attribute__((no_sanitize("signed-integer-overflow")))
floor1_inverse2(vorbis_dsp_state * vd,vorbis_info_floor * in,ogg_int32_t * fit_value,ogg_int32_t * out)378*bda690e4SXin Li int floor1_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *in,
379*bda690e4SXin Li 		    ogg_int32_t *fit_value,ogg_int32_t *out){
380*bda690e4SXin Li   vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
381*bda690e4SXin Li 
382*bda690e4SXin Li   codec_setup_info   *ci=(codec_setup_info *)vd->vi->codec_setup;
383*bda690e4SXin Li   int                  n=ci->blocksizes[vd->W]/2;
384*bda690e4SXin Li   int j;
385*bda690e4SXin Li 
386*bda690e4SXin Li   if(fit_value){
387*bda690e4SXin Li     /* render the lines */
388*bda690e4SXin Li     int hx=0;
389*bda690e4SXin Li     int lx=0;
390*bda690e4SXin Li     int ly=fit_value[0]*info->mult;
391*bda690e4SXin Li     for(j=1;j<info->posts;j++){
392*bda690e4SXin Li       int current=info->forward_index[j];
393*bda690e4SXin Li       int hy=fit_value[current]&0x7fff;
394*bda690e4SXin Li       if(hy==fit_value[current]){
395*bda690e4SXin Li 
396*bda690e4SXin Li 	hy*=info->mult;
397*bda690e4SXin Li 	hx=info->postlist[current];
398*bda690e4SXin Li 
399*bda690e4SXin Li 	render_line(n,lx,hx,ly,hy,out);
400*bda690e4SXin Li 
401*bda690e4SXin Li 	lx=hx;
402*bda690e4SXin Li 	ly=hy;
403*bda690e4SXin Li       }
404*bda690e4SXin Li     }
405*bda690e4SXin Li     for(j=hx;j<n;j++)out[j]*=ly; /* be certain */
406*bda690e4SXin Li     return(1);
407*bda690e4SXin Li   }
408*bda690e4SXin Li   memset(out,0,sizeof(*out)*n);
409*bda690e4SXin Li   return(0);
410*bda690e4SXin Li }
411