Remove multiple subtly different inline and static implementaitonos of ilog()
authorMonty <xiphmont@xiph.org>
Wed, 21 Jan 2015 01:17:41 +0000 (01:17 +0000)
committerMonty <xiphmont@xiph.org>
Wed, 21 Jan 2015 01:17:41 +0000 (01:17 +0000)
Add a few additional sanity checks, mostly functioning to ensure we're always
calling ilog() with >=0 input.

svn path=/trunk/vorbis/; revision=19441

lib/block.c
lib/codebook.c
lib/codebook.h
lib/floor0.c
lib/floor1.c
lib/info.c
lib/mapping0.c
lib/misc.h
lib/res0.c
lib/sharedbook.c
lib/synthesis.c

index dfcd843..7fdf6ef 100644 (file)
 #include "registry.h"
 #include "misc.h"
 
-static int ilog2(unsigned int v){
-  int ret=0;
-  if(v)--v;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
 /* pcm accumulator examples (not exhaustive):
 
  <-------------- lW ---------------->
@@ -184,14 +174,19 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
   private_state *b=NULL;
   int hs;
 
-  if(ci==NULL) return 1;
+  if(ci==NULL||
+     ci->modes<=0||
+     ci->blocksizes[0]<64||
+     ci->blocksizes[1]<ci->blocksizes[0]){
+    return 1;
+  }
   hs=ci->halfrate_flag;
 
   memset(v,0,sizeof(*v));
   b=v->backend_state=_ogg_calloc(1,sizeof(*b));
 
   v->vi=vi;
-  b->modebits=ilog2(ci->modes);
+  b->modebits=ov_ilog(ci->modes-1);
 
   b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
   b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
@@ -204,8 +199,14 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
   mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
 
   /* Vorbis I uses only window type 0 */
-  b->window[0]=ilog2(ci->blocksizes[0])-6;
-  b->window[1]=ilog2(ci->blocksizes[1])-6;
+  /* note that the correct computation below is technically:
+       b->window[0]=ov_ilog(ci->blocksizes[0]-1)-6;
+       b->window[1]=ov_ilog(ci->blocksizes[1]-1)-6;
+    but since blocksizes are always powers of two,
+    the below is equivalent.
+   */
+  b->window[0]=ov_ilog(ci->blocksizes[0])-7;
+  b->window[1]=ov_ilog(ci->blocksizes[1])-7;
 
   if(encp){ /* encode/decode differ here */
 
index db0066c..7ec6311 100644 (file)
@@ -57,12 +57,12 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
       char last=c->lengthlist[i-1];
       if(this>last){
         for(j=last;j<this;j++){
-          oggpack_write(opb,i-count,_ilog(c->entries-count));
+          oggpack_write(opb,i-count,ov_ilog(c->entries-count));
           count=i;
         }
       }
     }
-    oggpack_write(opb,i-count,_ilog(c->entries-count));
+    oggpack_write(opb,i-count,ov_ilog(c->entries-count));
 
   }else{
     /* length random.  Again, we don't code the codeword itself, just
@@ -159,7 +159,7 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
   s->entries=oggpack_read(opb,24);
   if(s->entries==-1)goto _eofout;
 
-  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
+  if(ov_ilog(s->dim)+ov_ilog(s->entries)>24)goto _eofout;
 
   /* codeword ordering.... length ordered or unordered? */
   switch((int)oggpack_read(opb,1)){
@@ -203,7 +203,7 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
       s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
 
       for(i=0;i<s->entries;){
-        long num=oggpack_read(opb,_ilog(s->entries-i));
+        long num=oggpack_read(opb,ov_ilog(s->entries-i));
         if(num==-1)goto _eofout;
         if(length>32 || num>s->entries-i ||
            (num>0 && (num-1)>>(length-1)>1)){
index 4c83af5..014e1e1 100644 (file)
@@ -89,7 +89,6 @@ extern float *_book_logdist(const static_codebook *b,float *vals);
 extern float _float32_unpack(long val);
 extern long   _float32_pack(float val);
 extern int  _best(codebook *book, float *a, int step);
-extern int _ilog(unsigned int v);
 extern long _book_maptype1_quantvals(const static_codebook *b);
 
 extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul);
index 7827f50..b4402e6 100644 (file)
@@ -168,7 +168,7 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
   if(ampraw>0){ /* also handles the -1 out of data case */
     long maxval=(1<<info->ampbits)-1;
     float amp=(float)ampraw/maxval*info->ampdB;
-    int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
+    int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
 
     if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
       codec_setup_info  *ci=vb->vd->vi->codec_setup;
index 54527ac..49ef52d 100644 (file)
@@ -72,25 +72,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 +98,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]];
@@ -854,9 +837,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 */
@@ -980,8 +963,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++){
index fed4582..e447a0c 100644 (file)
 #define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20150105 (⛄⛄⛄⛄)"
 
 /* helpers */
-static int ilog2(unsigned int v){
-  int ret=0;
-  if(v)--v;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
 static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
 
   while(bytes--){
@@ -447,7 +437,11 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
 
 static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
   codec_setup_info     *ci=vi->codec_setup;
-  if(!ci)return(OV_EFAULT);
+  if(!ci||
+     ci->blocksizes[0]<64||
+     ci->blocksizes[1]<ci->blocksizes[0]){
+    return(OV_EFAULT);
+  }
 
   /* preamble */
   oggpack_write(opb,0x01,8);
@@ -462,8 +456,8 @@ static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
   oggpack_write(opb,vi->bitrate_nominal,32);
   oggpack_write(opb,vi->bitrate_lower,32);
 
-  oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
-  oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
+  oggpack_write(opb,ov_ilog(ci->blocksizes[0]-1),4);
+  oggpack_write(opb,ov_ilog(ci->blocksizes[1]-1),4);
   oggpack_write(opb,1,1);
 
   return(0);
@@ -589,7 +583,7 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v,
   oggpack_buffer opb;
   private_state *b=v->backend_state;
 
-  if(!b){
+  if(!b||vi->channels<=0){
     ret=OV_EFAULT;
     goto err_out;
   }
index e0be6a0..8a7a04c 100644 (file)
@@ -45,16 +45,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 +68,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);
@@ -104,6 +94,7 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
   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 +110,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 ||
index b5f8a4a..a6eaa90 100644 (file)
@@ -21,6 +21,7 @@
 
 extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
 extern void _vorbis_block_ripcord(vorbis_block *vb);
+extern int ov_ilog(unsigned int v);
 
 #ifdef ANALYSIS
 extern int analysis_noisy;
index bca6e47..837f5fd 100644 (file)
@@ -152,15 +152,6 @@ void res0_free_look(vorbis_look_residue *i){
   }
 }
 
-static int ilog(unsigned int v){
-  int ret=0;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
-}
-
 static int icount(unsigned int v){
   int ret=0;
   while(v){
@@ -186,7 +177,7 @@ void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
      bitmask of one indicates this partition class has bits to write
      this pass */
   for(j=0;j<info->partitions;j++){
-    if(ilog(info->secondstages[j])>3){
+    if(ov_ilog(info->secondstages[j])>3){
       /* yes, this is a minor hack due to not thinking ahead */
       oggpack_write(opb,info->secondstages[j],3);
       oggpack_write(opb,1,1);
@@ -284,7 +275,7 @@ vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
   look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
 
   for(j=0;j<look->parts;j++){
-    int stages=ilog(info->secondstages[j]);
+    int stages=ov_ilog(info->secondstages[j]);
     if(stages){
       if(stages>maxstage)maxstage=stages;
       look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
index d389f67..926b0fb 100644 (file)
 #include "scales.h"
 
 /**** pack/unpack helpers ******************************************/
-int _ilog(unsigned int v){
-  int ret=0;
-  while(v){
-    ret++;
-    v>>=1;
-  }
-  return(ret);
+
+int ov_ilog(ogg_uint32_t v){
+  int ret;
+  for(ret=0;v;ret++)v>>=1;
+  return ret;
 }
 
 /* 32 bit float (not IEEE; nonnormalized mantissa +
@@ -374,7 +372,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
       if(s->lengthlist[i]>0)
         c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
 
-    c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
+    c->dec_firsttablen=ov_ilog(c->used_entries)-4; /* this is magic */
     if(c->dec_firsttablen<5)c->dec_firsttablen=5;
     if(c->dec_firsttablen>8)c->dec_firsttablen=8;
 
index f55091f..3fa5ab9 100644 (file)
@@ -145,6 +145,11 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
   oggpack_buffer       opb;
   int                  mode;
 
+  if(ci==NULL || ci->modes<=0){
+    /* codec setup not properly intialized */
+    return(OV_EFAULT);
+  }
+
   oggpack_readinit(&opb,op->packet,op->bytes);
 
   /* Check the packet type */
@@ -153,17 +158,8 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
     return(OV_ENOTAUDIO);
   }
 
-  {
-    int modebits=0;
-    int v=ci->modes;
-    while(v>1){
-      modebits++;
-      v>>=1;
-    }
-
-    /* read our mode and pre/post windowsize */
-    mode=oggpack_read(&opb,modebits);
-  }
+  /* read our mode and pre/post windowsize */
+  mode=oggpack_read(&opb,ov_ilog(ci->modes-1));
   if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET);
   return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
 }