Remove svn $Id$ header.
[platform/upstream/libvorbis.git] / lib / floor1.c
index 7c74e37..673e954 100644 (file)
@@ -5,13 +5,12 @@
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015             *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
  function: floor backend 1 implementation
- last mod: $Id$
 
  ********************************************************************/
 
@@ -72,25 +71,6 @@ static void floor1_free_look(vorbis_look_floor *i){
   }
 }
 
-static int ilog(unsigned int v){
-  int ret=0;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
-static int ilog2(unsigned int v){
-  int ret=0;
-  if(v)--v;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
 static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
   vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
   int j,k;
@@ -117,8 +97,10 @@ static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
 
   /* save out the post list */
   oggpack_write(opb,info->mult-1,2);     /* only 1,2,3,4 legal now */
-  oggpack_write(opb,ilog2(maxposit),4);
-  rangebits=ilog2(maxposit);
+  /* maxposit cannot legally be less than 1; this is encode-side, we
+     can assume our setup is OK */
+  oggpack_write(opb,ov_ilog(maxposit-1),4);
+  rangebits=ov_ilog(maxposit-1);
 
   for(j=0,k=0;j<info->partitions;j++){
     count+=info->class_dim[info->partitionclass[j]];
@@ -167,6 +149,7 @@ static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
 
   for(j=0,k=0;j<info->partitions;j++){
     count+=info->class_dim[info->partitionclass[j]];
+    if(count>VIF_POSIT) goto err_out;
     for(;k<count;k++){
       int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
       if(t<0 || t>=(1<<rangebits))
@@ -202,6 +185,8 @@ static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
   vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
   int i,j,n=0;
 
+  (void)vd;
+
   look->vi=info;
   look->n=info->postlist[1];
 
@@ -470,27 +455,20 @@ static int accumulate_fit(const float *flr,const float *mdct,
 
 static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1,
                     vorbis_info_floor1 *info){
-  double weight;
-  double xa=0,ya=0,x2a=0,y2a=0,xya=0,an=0;
   double xb=0,yb=0,x2b=0,y2b=0,xyb=0,bn=0;
   int i;
   int x0=a[0].x0;
   int x1=a[fits-1].x1;
 
   for(i=0;i<fits;i++){
-    xa+=a[i].xa;
-    ya+=a[i].ya;
-    x2a+=a[i].x2a;
-    y2a+=a[i].y2a;
-    xya+=a[i].xya;
-    an+=a[i].an;
-
-    xb+=a[i].xb;
-    yb+=a[i].yb;
-    x2b+=a[i].x2b;
-    y2b+=a[i].y2b;
-    xyb+=a[i].xyb;
-    bn+=a[i].bn;
+    double weight = (a[i].bn+a[i].an)*info->twofitweight/(a[i].an+1)+1.;
+
+    xb+=a[i].xb + a[i].xa * weight;
+    yb+=a[i].yb + a[i].ya * weight;
+    x2b+=a[i].x2b + a[i].x2a * weight;
+    y2b+=a[i].y2b + a[i].y2a * weight;
+    xyb+=a[i].xyb + a[i].xya * weight;
+    bn+=a[i].bn + a[i].an * weight;
   }
 
   if(*y0>=0){
@@ -511,14 +489,6 @@ static int fit_line(lsfit_acc *a,int fits,int *y0,int *y1,
     bn++;
   }
 
-  weight = (bn*an)*info->twofitweight/(an+1)+1.;
-  xb += xa * weight;
-  yb += ya * weight;
-  x2b += x2a * weight;
-  y2b += y2a * weight;
-  xyb += xya * weight;
-  bn += an * weight;
-
   {
     double denom=(bn*x2b-xb*xb);
 
@@ -866,9 +836,9 @@ int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
 
     /* beginning/end post */
     look->frames++;
-    look->postbits+=ilog(look->quant_q-1)*2;
-    oggpack_write(opb,out[0],ilog(look->quant_q-1));
-    oggpack_write(opb,out[1],ilog(look->quant_q-1));
+    look->postbits+=ov_ilog(look->quant_q-1)*2;
+    oggpack_write(opb,out[0],ov_ilog(look->quant_q-1));
+    oggpack_write(opb,out[1],ov_ilog(look->quant_q-1));
 
 
     /* partition by partition */
@@ -884,7 +854,9 @@ int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
 
       /* generate the partition's first stage cascade value */
       if(csubbits){
-        int maxval[8];
+        int maxval[8]={0,0,0,0,0,0,0,0}; /* gcc's static analysis
+                                            issues a warning without
+                                            initialization */
         for(k=0;k<csub;k++){
           int booknum=info->class_subbook[class][k];
           if(booknum<0){
@@ -992,8 +964,8 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
   if(oggpack_read(&vb->opb,1)==1){
     int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
 
-    fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
-    fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
+    fit_value[0]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1));
+    fit_value[1]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1));
 
     /* partition by partition */
     for(i=0,j=2;i<info->partitions;i++){
@@ -1050,7 +1022,7 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
           }
         }
 
-        fit_value[i]=val+predicted;
+        fit_value[i]=(val+predicted)&0x7fff;
         fit_value[look->loneighbor[i-2]]&=0x7fff;
         fit_value[look->hineighbor[i-2]]&=0x7fff;
 
@@ -1081,13 +1053,18 @@ static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
     int hx=0;
     int lx=0;
     int ly=fit_value[0]*info->mult;
+    /* guard lookup against out-of-range values */
+    ly=(ly<0?0:ly>255?255:ly);
+
     for(j=1;j<look->posts;j++){
       int current=look->forward_index[j];
       int hy=fit_value[current]&0x7fff;
       if(hy==fit_value[current]){
 
-        hy*=info->mult;
         hx=info->postlist[current];
+        hy*=info->mult;
+        /* guard lookup against out-of-range values */
+        hy=(hy<0?0:hy>255?255:hy);
 
         render_line(n,lx,hx,ly,hy,out);