Instead of SIGFPE when bytespersample is zero or negative, return OV_EINVAL
[platform/upstream/libvorbis.git] / lib / mapping0.c
index 988cfec..ccb4493 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-2010             *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
  function: channel mapping 0 implementation
- last mod: $Id$
 
  ********************************************************************/
 
@@ -45,16 +44,6 @@ static void mapping0_free_info(vorbis_info_mapping *i){
   }
 }
 
-static int ilog(unsigned int v){
-  int ret=0;
-  if(v)--v;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
 static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
                           oggpack_buffer *opb){
   int i;
@@ -78,8 +67,8 @@ static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
     oggpack_write(opb,info->coupling_steps-1,8);
 
     for(i=0;i<info->coupling_steps;i++){
-      oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels));
-      oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels));
+      oggpack_write(opb,info->coupling_mag[i],ov_ilog(vi->channels-1));
+      oggpack_write(opb,info->coupling_ang[i],ov_ilog(vi->channels-1));
     }
   }else
     oggpack_write(opb,0,1);
@@ -103,7 +92,7 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
   int i,b;
   vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
   codec_setup_info     *ci=vi->codec_setup;
-  memset(info,0,sizeof(*info));
+  if(vi->channels<=0)goto err_out;
 
   b=oggpack_read(opb,1);
   if(b<0)goto err_out;
@@ -119,8 +108,11 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
     info->coupling_steps=oggpack_read(opb,8)+1;
     if(info->coupling_steps<=0)goto err_out;
     for(i=0;i<info->coupling_steps;i++){
-      int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
-      int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
+      /* vi->channels > 0 is enforced in the caller */
+      int testM=info->coupling_mag[i]=
+        oggpack_read(opb,ov_ilog(vi->channels-1));
+      int testA=info->coupling_ang[i]=
+        oggpack_read(opb,ov_ilog(vi->channels-1));
 
       if(testM<0 ||
          testA<0 ||
@@ -600,36 +592,6 @@ static int mapping0_forward(vorbis_block *vb){
   {
     int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
     int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
-    int **sortindex=alloca(sizeof(*sortindex)*vi->channels);
-    float **mag_memo=NULL;
-    int **mag_sort=NULL;
-
-    if(info->coupling_steps){
-      mag_memo=_vp_quantize_couple_memo(vb,
-                                        &ci->psy_g_param,
-                                        psy_look,
-                                        info,
-                                        gmdct);
-
-      mag_sort=_vp_quantize_couple_sort(vb,
-                                        psy_look,
-                                        info,
-                                        mag_memo);
-
-      hf_reduction(&ci->psy_g_param,
-                   psy_look,
-                   info,
-                   mag_memo);
-    }
-
-    memset(sortindex,0,sizeof(*sortindex)*vi->channels);
-    if(psy_look->vi->normal_channel_p){
-      for(i=0;i<vi->channels;i++){
-        float *mdct    =gmdct[i];
-        sortindex[i]=alloca(sizeof(**sortindex)*n/2);
-        _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]);
-      }
-    }
 
     for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
         k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
@@ -650,9 +612,7 @@ static int mapping0_forward(vorbis_block *vb){
       /* encode floor, compute masking curve, sep out residue */
       for(i=0;i<vi->channels;i++){
         int submap=info->chmuxlist[i];
-        float *mdct    =gmdct[i];
-        float *res     =vb->pcm[i];
-        int   *ilogmask=iwork[i];
+        int *ilogmask=iwork[i];
 
         nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
                                  floor_posts[i][k],
@@ -663,30 +623,10 @@ static int mapping0_forward(vorbis_block *vb){
           sprintf(buf,"maskI%c%d",i?'R':'L',k);
           float work[n/2];
           for(j=0;j<n/2;j++)
-            work[j]=FLOOR1_fromdB_LOOKUP[iwork[j]];
+            work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
           _analysis_output(buf,seq,work,n/2,1,1,0);
         }
 #endif
-        _vp_remove_floor(psy_look,
-                         mdct,
-                         ilogmask,
-                         res,
-                         ci->psy_g_param.sliding_lowpass[vb->W][k]);
-
-        _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]);
-
-
-#if 0
-        {
-          char buf[80];
-          float work[n/2];
-          for(j=0;j<n/2;j++)
-            work[j]=FLOOR1_fromdB_LOOKUP[iwork[j]]*(res+n/2)[j];
-          sprintf(buf,"resI%c%d",i?'R':'L',k);
-          _analysis_output(buf,seq,work,n/2,1,1,0);
-
-        }
-#endif
       }
 
       /* our iteration is now based on masking curve, not prequant and
@@ -695,24 +635,26 @@ static int mapping0_forward(vorbis_block *vb){
       /* quantize/couple */
       /* incomplete implementation that assumes the tree is all depth
          one, or no tree at all */
-      if(info->coupling_steps){
-        _vp_couple(k,
-                   &ci->psy_g_param,
-                   psy_look,
-                   info,
-                   vb->pcm,
-                   mag_memo,
-                   mag_sort,
-                   iwork,
-                   nonzero,
-                   ci->psy_g_param.sliding_lowpass[vb->W][k]);
-      }
-      for(j=0;j<vi->channels;j++){
-        int *ires = iwork[j];
-        float *res = vb->pcm[j]+n/2;
-        for(i=0;i<n/2;i++)
-          ires[i] = (int)rint(res[i]);
+      _vp_couple_quantize_normalize(k,
+                                    &ci->psy_g_param,
+                                    psy_look,
+                                    info,
+                                    gmdct,
+                                    iwork,
+                                    nonzero,
+                                    ci->psy_g_param.sliding_lowpass[vb->W][k],
+                                    vi->channels);
+
+#if 0
+      for(i=0;i<vi->channels;i++){
+        char buf[80];
+        sprintf(buf,"res%c%d",i?'R':'L',k);
+        float work[n/2];
+        for(j=0;j<n/2;j++)
+          work[j]=iwork[i][j];
+        _analysis_output(buf,seq,work,n/2,1,0,0);
       }
+#endif
 
       /* classify and encode by submap */
       for(i=0;i<info->submaps;i++){
@@ -738,7 +680,7 @@ static int mapping0_forward(vorbis_block *vb){
 
         _residue_P[ci->residue_type[resnum]]->
           forward(opb,vb,b->residue[resnum],
-                  couple_bundle,zerobundle,ch_in_bundle,classifications);
+                  couple_bundle,zerobundle,ch_in_bundle,classifications,i);
       }
 
       /* ok, done encoding.  Next protopacket. */