summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2015-01-21 01:17:41 +0000
committerMonty <xiphmont@xiph.org>2015-01-21 01:17:41 +0000
commit4b67376da7ded7f16dfebb8a05fb559ac7fbcf55 (patch)
tree80b92bfe5790338ee179c02e68440661a4b03d8a
parentd61e0b2a8ae2d8743c9807bf7aa6896151ccec7f (diff)
downloadlibvorbis-git-4b67376da7ded7f16dfebb8a05fb559ac7fbcf55.tar.gz
Remove multiple subtly different inline and static implementaitonos of ilog()
Add a few additional sanity checks, mostly functioning to ensure we're always calling ilog() with >=0 input. svn path=/trunk/vorbis/; revision=19441
-rw-r--r--lib/block.c29
-rw-r--r--lib/codebook.c8
-rw-r--r--lib/codebook.h1
-rw-r--r--lib/floor0.c2
-rw-r--r--lib/floor1.c35
-rw-r--r--lib/info.c22
-rw-r--r--lib/mapping0.c22
-rw-r--r--lib/misc.h1
-rw-r--r--lib/res0.c13
-rw-r--r--lib/sharedbook.c14
-rw-r--r--lib/synthesis.c18
11 files changed, 61 insertions, 104 deletions
diff --git a/lib/block.c b/lib/block.c
index dfcd843f..7fdf6ef4 100644
--- a/lib/block.c
+++ b/lib/block.c
@@ -31,16 +31,6 @@
#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 */
diff --git a/lib/codebook.c b/lib/codebook.c
index db0066c6..7ec6311b 100644
--- a/lib/codebook.c
+++ b/lib/codebook.c
@@ -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)){
diff --git a/lib/codebook.h b/lib/codebook.h
index 4c83af56..014e1e1a 100644
--- a/lib/codebook.h
+++ b/lib/codebook.h
@@ -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);
diff --git a/lib/floor0.c b/lib/floor0.c
index 7827f50a..b4402e61 100644
--- a/lib/floor0.c
+++ b/lib/floor0.c
@@ -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;
diff --git a/lib/floor1.c b/lib/floor1.c
index 54527ac0..49ef52df 100644
--- a/lib/floor1.c
+++ b/lib/floor1.c
@@ -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++){
diff --git a/lib/info.c b/lib/info.c
index fed45823..e447a0ce 100644
--- a/lib/info.c
+++ b/lib/info.c
@@ -35,16 +35,6 @@
#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;
}
diff --git a/lib/mapping0.c b/lib/mapping0.c
index e0be6a0c..8a7a04c6 100644
--- a/lib/mapping0.c
+++ b/lib/mapping0.c
@@ -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 ||
diff --git a/lib/misc.h b/lib/misc.h
index b5f8a4aa..a6eaa908 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -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;
diff --git a/lib/res0.c b/lib/res0.c
index bca6e47a..837f5fdc 100644
--- a/lib/res0.c
+++ b/lib/res0.c
@@ -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]));
diff --git a/lib/sharedbook.c b/lib/sharedbook.c
index d389f675..926b0fbd 100644
--- a/lib/sharedbook.c
+++ b/lib/sharedbook.c
@@ -26,13 +26,11 @@
#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;
diff --git a/lib/synthesis.c b/lib/synthesis.c
index f55091ff..3fa5ab93 100644
--- a/lib/synthesis.c
+++ b/lib/synthesis.c
@@ -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]);
}