#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 ---------------->
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]));
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 */
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
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)){
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)){
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);
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;
}
}
-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;
/* 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]];
/* 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 */
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++){
#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--){
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);
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);
oggpack_buffer opb;
private_state *b=v->backend_state;
- if(!b){
+ if(!b||vi->channels<=0){
ret=OV_EFAULT;
goto err_out;
}
}
}
-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;
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);
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;
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 ||
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;
}
}
-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){
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);
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]));
#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 +
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;
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 */
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]);
}