diff --git a/CMakeLists.txt b/CMakeLists.txt index e78fc37b4..cea427347 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.20) project(vorbis) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -10,7 +10,6 @@ include(CheckIncludeFiles) include(CheckLibraryExists) # Build options -option(BUILD_SHARED_LIBS "Build shared library" OFF) if(APPLE) option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF) endif() diff --git a/lib/block.c b/lib/block.c index d7162ae6b..6d6bef98b 100644 --- a/lib/block.c +++ b/lib/block.c @@ -21,6 +21,7 @@ #include #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "codec_internal.h" @@ -425,8 +426,8 @@ float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){ static void _preextrapolate_helper(vorbis_dsp_state *v){ int i; int order=16; - float *lpc=alloca(order*sizeof(*lpc)); - float *work=alloca(v->pcm_current*sizeof(*work)); + float *lpc=VORBIS_STACK_ALLOC(order*sizeof(*lpc)); + float *work=VORBIS_STACK_ALLOC(v->pcm_current*sizeof(*work)); long j; v->preextrapolate=1; @@ -461,6 +462,8 @@ static void _preextrapolate_helper(vorbis_dsp_state *v){ } } + VORBIS_STACK_FREE(work); + VORBIS_STACK_FREE(lpc); } @@ -473,7 +476,7 @@ int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){ if(vals<=0){ int order=32; int i; - float *lpc=alloca(order*sizeof(*lpc)); + float *lpc=VORBIS_STACK_ALLOC(order*sizeof(*lpc)); /* if it wasn't done earlier (very short sample) */ if(!v->preextrapolate) @@ -511,6 +514,7 @@ int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){ } } + VORBIS_STACK_FREE(lpc); }else{ if(v->pcm_current+vals>v->pcm_storage) diff --git a/lib/codebook.c b/lib/codebook.c index 7a0c20678..26c37cdfc 100644 --- a/lib/codebook.c +++ b/lib/codebook.c @@ -18,6 +18,7 @@ #include #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "codebook.h" #include "scales.h" @@ -376,18 +377,25 @@ long vorbis_book_decode(codebook *book, oggpack_buffer *b){ long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){ if(book->used_entries>0){ int step=n/book->dim; - long *entry = alloca(sizeof(*entry)*step); - float **t = alloca(sizeof(*t)*step); + long *entry = VORBIS_STACK_ALLOC(sizeof(*entry)*step); + float **t = VORBIS_STACK_ALLOC(sizeof(*t)*step); int i,j,o; for (i = 0; i < step; i++) { entry[i]=decode_packed_entry_number(book,b); - if(entry[i]==-1)return(-1); + if(entry[i]==-1) { + VORBIS_STACK_FREE(t); + VORBIS_STACK_FREE(entry); + return(-1); + } t[i] = book->valuelist+entry[i]*book->dim; } for(i=0,o=0;idim;i++,o+=step) for (j=0;o+j #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "codec_internal.h" @@ -101,7 +102,7 @@ static int _ve_amp(envelope_lookup *ve, itself (for low power signals) */ float minV=ve->minenergy; - float *vec=alloca(n*sizeof(*vec)); + float *vec=VORBIS_STACK_ALLOC(n*sizeof(*vec)); /* stretch is used to gradually lengthen the number of windows considered prevoius-to-potential-trigger */ @@ -204,6 +205,8 @@ static int _ve_amp(envelope_lookup *ve, if(valminpostecho_thresh[j]-penalty)ret|=2; } + VORBIS_STACK_FREE(vec); + return(ret); } @@ -278,7 +281,7 @@ long _ve_envelope_search(vorbis_dsp_state *v){ #if 0 if(j>ve->curmark){ - float *marker=alloca(v->pcm_current*sizeof(*marker)); + float *marker=VORBIS_STACK_ALLOC(v->pcm_current*sizeof(*marker)); int l,m; memset(marker,0,sizeof(*marker)*v->pcm_current); fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n", diff --git a/lib/lpc.c b/lib/lpc.c index 877da47f8..84d68fd83 100644 --- a/lib/lpc.c +++ b/lib/lpc.c @@ -45,6 +45,7 @@ Carsten Bormann #include #include #include +#include "stack_alloc.h" #include "os.h" #include "smallft.h" #include "lpc.h" @@ -58,8 +59,8 @@ Carsten Bormann Output: m lpc coefficients, excitation energy */ float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){ - double *aut=alloca(sizeof(*aut)*(m+1)); - double *lpc=alloca(sizeof(*lpc)*(m)); + double *aut=VORBIS_STACK_ALLOC(sizeof(*aut)*(m+1)); + double *lpc=VORBIS_STACK_ALLOC(sizeof(*lpc)*(m)); double error; double epsilon; int i,j; @@ -126,6 +127,9 @@ float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){ /* we need the error value to know how big an impulse to hit the filter with later */ + VORBIS_STACK_FREE(aut); + VORBIS_STACK_FREE(lpc); + return error; } @@ -138,7 +142,7 @@ void vorbis_lpc_predict(float *coeff,float *prime,int m, long i,j,o,p; float y; - float *work=alloca(sizeof(*work)*(m+n)); + float *work=VORBIS_STACK_ALLOC(sizeof(*work)*(m+n)); if(!prime) for(i=0;i #include #include +#include "stack_alloc.h" #include "lsp.h" #include "os.h" #include "misc.h" @@ -146,7 +147,7 @@ void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, int i; int ampoffseti=rint(ampoffset*4096.f); int ampi=rint(amp*16.f); - long *ilsp=alloca(m*sizeof(*ilsp)); + long *ilsp=VORBIS_STACK_ALLOC(m*sizeof(*ilsp)); for(i=0;i0;m--){ @@ -328,8 +330,10 @@ static int Laguerre_With_Deflation(float *a,int ord,float *r){ /* Laguerre's method */ denom=(m-1) * ((m-1)*pp*pp - m*p*ppp); - if(denom<0) - return(-1); /* complex root! The LPC generator handed us a bad filter */ + if(denom<0){ /* complex root! The LPC generator handed us a bad filter */ + VORBIS_STACK_FREE(defl); + return(-1); + } if(pp>0){ denom = pp + sqrt(denom); @@ -356,6 +360,7 @@ static int Laguerre_With_Deflation(float *a,int ord,float *r){ defl++; } + VORBIS_STACK_FREE(defl); return(0); } @@ -364,7 +369,7 @@ static int Laguerre_With_Deflation(float *a,int ord,float *r){ static int Newton_Raphson(float *a,int ord,float *r){ int i, k, count=0; double error=1.f; - double *root=alloca(ord*sizeof(*root)); + double *root=VORBIS_STACK_ALLOC(ord*sizeof(*root)); for(i=0; i40)return(-1); + if(count>40){ + VORBIS_STACK_FREE(root); + return(-1); + } count++; } @@ -395,6 +403,7 @@ static int Newton_Raphson(float *a,int ord,float *r){ help, we can eliminate the bubble sort in our lifetime. --Monty */ for(i=0; i>1; int g1_order,g2_order; - float *g1=alloca(sizeof(*g1)*(order2+1)); - float *g2=alloca(sizeof(*g2)*(order2+1)); - float *g1r=alloca(sizeof(*g1r)*(order2+1)); - float *g2r=alloca(sizeof(*g2r)*(order2+1)); + float *g1=VORBIS_STACK_ALLOC(sizeof(*g1)*(order2+1)); + float *g2=VORBIS_STACK_ALLOC(sizeof(*g2)*(order2+1)); + float *g1r=VORBIS_STACK_ALLOC(sizeof(*g1r)*(order2+1)); + float *g2r=VORBIS_STACK_ALLOC(sizeof(*g2r)*(order2+1)); int i; /* even and odd are slightly different base cases */ @@ -436,8 +445,13 @@ int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){ /* Find the roots of the 2 even polynomials.*/ if(Laguerre_With_Deflation(g1,g1_order,g1r) || - Laguerre_With_Deflation(g2,g2_order,g2r)) + Laguerre_With_Deflation(g2,g2_order,g2r)) { + VORBIS_STACK_FREE(g2r); + VORBIS_STACK_FREE(g1r); + VORBIS_STACK_FREE(g2); + VORBIS_STACK_FREE(g1); return(-1); + } Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */ Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */ @@ -450,5 +464,10 @@ int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){ for(i=0;i #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "codec_internal.h" #include "codebook.h" @@ -236,13 +237,13 @@ static int mapping0_forward(vorbis_block *vb){ int n=vb->pcmend; int i,j,k; - int *nonzero = alloca(sizeof(*nonzero)*vi->channels); + int *nonzero = VORBIS_STACK_ALLOC(sizeof(*nonzero)*vi->channels); float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct)); int **iwork = _vorbis_block_alloc(vb,vi->channels*sizeof(*iwork)); int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts)); float global_ampmax=vbi->ampmax; - float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels); + float *local_ampmax=VORBIS_STACK_ALLOC(sizeof(*local_ampmax)*vi->channels); int blocktype=vbi->blocktype; int modenumber=vb->W; @@ -495,7 +496,11 @@ static int mapping0_forward(vorbis_block *vb){ /* this algorithm is hardwired to floor 1 for now; abort out if we're *not* floor1. This won't happen unless someone has broken the encode setup lib. Guard it anyway. */ - if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); + if(ci->floor_type[info->floorsubmap[submap]]!=1) { + VORBIS_STACK_FREE(local_ampmax); + VORBIS_STACK_FREE(nonzero); + return(-1); + } floor_posts[i][PACKETBLOBS/2]= floor1_fit(vb,b->flr[info->floorsubmap[submap]], @@ -590,8 +595,8 @@ static int mapping0_forward(vorbis_block *vb){ /* iterate over the many masking curve fits we've created */ { - int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels); - int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); + int **couple_bundle=VORBIS_STACK_ALLOC(sizeof(*couple_bundle)*vi->channels); + int *zerobundle=VORBIS_STACK_ALLOC(sizeof(*zerobundle)*vi->channels); for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); @@ -686,12 +691,16 @@ static int mapping0_forward(vorbis_block *vb){ /* ok, done encoding. Next protopacket. */ } + VORBIS_STACK_FREE(zerobundle); + VORBIS_STACK_FREE(couple_bundle); } #if 0 seq++; total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; #endif + VORBIS_STACK_FREE(local_ampmax); + VORBIS_STACK_FREE(nonzero); return(0); } @@ -705,11 +714,11 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ int i,j; long n=vb->pcmend=ci->blocksizes[vb->W]; - float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels); - int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels); + float **pcmbundle=VORBIS_STACK_ALLOC(sizeof(*pcmbundle)*vi->channels); + int *zerobundle=VORBIS_STACK_ALLOC(sizeof(*zerobundle)*vi->channels); - int *nonzero =alloca(sizeof(*nonzero)*vi->channels); - void **floormemo=alloca(sizeof(*floormemo)*vi->channels); + int *nonzero =VORBIS_STACK_ALLOC(sizeof(*nonzero)*vi->channels); + void **floormemo=VORBIS_STACK_ALLOC(sizeof(*floormemo)*vi->channels); /* recover the spectral envelope; store it in the PCM vector for now */ for(i=0;ichannels;i++){ @@ -794,6 +803,11 @@ static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ mdct_backward(b->transform[vb->W][0],pcm,pcm); } + VORBIS_STACK_FREE(floormemo); + VORBIS_STACK_FREE(nonzero); + VORBIS_STACK_FREE(zerobundle); + VORBIS_STACK_FREE(pcmbundle); + /* all done! */ return(0); } diff --git a/lib/mdct.c b/lib/mdct.c index 2a0ff8d01..7015f1054 100644 --- a/lib/mdct.c +++ b/lib/mdct.c @@ -40,6 +40,7 @@ #include #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "mdct.h" #include "os.h" @@ -494,7 +495,7 @@ void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){ int n2=n>>1; int n4=n>>2; int n8=n>>3; - DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */ + DATA_TYPE *w=VORBIS_STACK_ALLOC(n*sizeof(*w)); /* forward needs working space */ DATA_TYPE *w2=w+n2; /* rotate */ @@ -559,4 +560,6 @@ void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){ w+=2; T+=2; } + + VORBIS_STACK_FREE(w); } diff --git a/lib/psy.c b/lib/psy.c index d0901bf27..881337c93 100644 --- a/lib/psy.c +++ b/lib/psy.c @@ -17,6 +17,7 @@ #include #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "codec_internal.h" @@ -88,7 +89,7 @@ static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n, float ath[EHMER_MAX]; float workc[P_BANDS][P_LEVELS][EHMER_MAX]; float athc[P_LEVELS][EHMER_MAX]; - float *brute_buffer=alloca(n*sizeof(*brute_buffer)); + float *brute_buffer=VORBIS_STACK_ALLOC(n*sizeof(*brute_buffer)); float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS); @@ -452,8 +453,8 @@ static void seed_loop(vorbis_look_psy *p, } static void seed_chase(float *seeds, int linesper, long n){ - long *posstack=alloca(n*sizeof(*posstack)); - float *ampstack=alloca(n*sizeof(*ampstack)); + long *posstack=VORBIS_STACK_ALLOC(n*sizeof(*posstack)); + float *ampstack=VORBIS_STACK_ALLOC(n*sizeof(*ampstack)); long stack=0; long pos=0; long i; @@ -550,11 +551,11 @@ static void bark_noise_hybridmp(int n,const long *b, const float offset, const int fixed){ - float *N=alloca(n*sizeof(*N)); - float *X=alloca(n*sizeof(*N)); - float *XX=alloca(n*sizeof(*N)); - float *Y=alloca(n*sizeof(*N)); - float *XY=alloca(n*sizeof(*N)); + float *N=VORBIS_STACK_ALLOC(n*sizeof(*N)); + float *X=VORBIS_STACK_ALLOC(n*sizeof(*N)); + float *XX=VORBIS_STACK_ALLOC(n*sizeof(*N)); + float *Y=VORBIS_STACK_ALLOC(n*sizeof(*N)); + float *XY=VORBIS_STACK_ALLOC(n*sizeof(*N)); float tN, tX, tXX, tY, tXY; int i; @@ -655,7 +656,14 @@ static void bark_noise_hybridmp(int n,const long *b, noise[i] = R - offset; } - if (fixed <= 0) return; + if (fixed <= 0) { + VORBIS_STACK_FREE(XY); + VORBIS_STACK_FREE(Y); + VORBIS_STACK_FREE(XX); + VORBIS_STACK_FREE(X); + VORBIS_STACK_FREE(N); + return; + } for (i = 0, x = 0.f; i < n; i++, x += 1.f) { hi = i + fixed / 2; @@ -701,6 +709,12 @@ static void bark_noise_hybridmp(int n,const long *b, R = (A + x * B) / D; if (R - offset < noise[i]) noise[i] = R - offset; } + + VORBIS_STACK_FREE(XY); + VORBIS_STACK_FREE(Y); + VORBIS_STACK_FREE(XX); + VORBIS_STACK_FREE(X); + VORBIS_STACK_FREE(N); } void _vp_noisemask(vorbis_look_psy *p, @@ -708,7 +722,7 @@ void _vp_noisemask(vorbis_look_psy *p, float *logmask){ int i,n=p->n; - float *work=alloca(n*sizeof(*work)); + float *work=VORBIS_STACK_ALLOC(n*sizeof(*work)); bark_noise_hybridmp(n,p->bark,logmdct,logmask, 140.,-1); @@ -749,6 +763,8 @@ void _vp_noisemask(vorbis_look_psy *p, logmask[i]= work[i]+p->vi->noisecompand[dB]; } + VORBIS_STACK_FREE(work); + } void _vp_tonemask(vorbis_look_psy *p, @@ -759,7 +775,7 @@ void _vp_tonemask(vorbis_look_psy *p, int i,n=p->n; - float *seed=alloca(sizeof(*seed)*p->total_octave_lines); + float *seed=VORBIS_STACK_ALLOC(sizeof(*seed)*p->total_octave_lines); float att=local_specmax+p->vi->ath_adjatt; for(i=0;itotal_octave_lines;i++)seed[i]=NEGINF; @@ -774,6 +790,7 @@ void _vp_tonemask(vorbis_look_psy *p, seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax); max_seeds(p,seed,logmask); + VORBIS_STACK_FREE(seed); } void _vp_offset_and_mix(vorbis_look_psy *p, @@ -941,7 +958,7 @@ static void flag_lossless(int limit, float prepoint, float postpoint, float *mdc static float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, float *f, int *flags, float acc, int i, int n, int *out){ vorbis_info_psy *vi=p->vi; - float **sort = alloca(n*sizeof(*sort)); + float **sort = VORBIS_STACK_ALLOC(n*sizeof(*sort)); int j,count=0; int start = (vi->normal_p ? vi->normal_start-i : n); if(start>n)start=n; @@ -1006,6 +1023,8 @@ static float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, } } + VORBIS_STACK_FREE(sort); + return acc; } @@ -1035,31 +1054,31 @@ void _vp_couple_quantize_normalize(int blobno, /* inout passes in the ifloor, passes back quantized result */ /* unquantized energy (negative indicates amplitude has negative sign) */ - float **raw = alloca(ch*sizeof(*raw)); + float **raw = VORBIS_STACK_ALLOC(ch*sizeof(*raw)); /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */ - float **quant = alloca(ch*sizeof(*quant)); + float **quant = VORBIS_STACK_ALLOC(ch*sizeof(*quant)); /* floor energy */ - float **floor = alloca(ch*sizeof(*floor)); + float **floor = VORBIS_STACK_ALLOC(ch*sizeof(*floor)); /* flags indicating raw/quantized status of elements in raw vector */ - int **flag = alloca(ch*sizeof(*flag)); + int **flag = VORBIS_STACK_ALLOC(ch*sizeof(*flag)); /* non-zero flag working vector */ - int *nz = alloca(ch*sizeof(*nz)); + int *nz = VORBIS_STACK_ALLOC(ch*sizeof(*nz)); /* energy surplus/defecit tracking */ - float *acc = alloca((ch+vi->coupling_steps)*sizeof(*acc)); + float *acc = VORBIS_STACK_ALLOC((ch+vi->coupling_steps)*sizeof(*acc)); /* The threshold of a stereo is changed with the size of n */ if(n > 1000) postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]]; - raw[0] = alloca(ch*partition*sizeof(**raw)); - quant[0] = alloca(ch*partition*sizeof(**quant)); - floor[0] = alloca(ch*partition*sizeof(**floor)); - flag[0] = alloca(ch*partition*sizeof(**flag)); + raw[0] = VORBIS_STACK_ALLOC(ch*partition*sizeof(**raw)); + quant[0] = VORBIS_STACK_ALLOC(ch*partition*sizeof(**quant)); + floor[0] = VORBIS_STACK_ALLOC(ch*partition*sizeof(**floor)); + flag[0] = VORBIS_STACK_ALLOC(ch*partition*sizeof(**flag)); for(i=1;icoupling_ang[i]]=1; } } + + VORBIS_STACK_FREE(flag[0]); + VORBIS_STACK_FREE(floor[0]); + VORBIS_STACK_FREE(quant[0]); + VORBIS_STACK_FREE(raw[0]); + VORBIS_STACK_FREE(acc); + VORBIS_STACK_FREE(nz); + VORBIS_STACK_FREE(flag); + VORBIS_STACK_FREE(floor); + VORBIS_STACK_FREE(quant); + VORBIS_STACK_FREE(raw); } diff --git a/lib/res0.c b/lib/res0.c index c931aded3..e4fb99717 100644 --- a/lib/res0.c +++ b/lib/res0.c @@ -23,6 +23,7 @@ #include #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" #include "codec_internal.h" #include "registry.h" @@ -656,10 +657,11 @@ static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, int end=(info->endend:max); int n=end-info->begin; + int ***partword=NULL; if(n>0){ int partvals=n/samples_per_partition; int partwords=(partvals+partitions_per_word-1)/partitions_per_word; - int ***partword=alloca(ch*sizeof(*partword)); + partword=VORBIS_STACK_ALLOC(ch*sizeof(*partword)); for(j=0;j #include #include +#include "stack_alloc.h" #include "os.h" #include "misc.h" #include "vorbis/codec.h" @@ -352,9 +353,12 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ /* perform sort */ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); - ogg_uint32_t **codep=alloca(sizeof(*codep)*n); + ogg_uint32_t **codep=VORBIS_STACK_ALLOC(sizeof(*codep)*n); - if(codes==NULL)goto err_out; + if(codes==NULL){ + VORBIS_STACK_FREE(codep); + goto err_out; + } for(i=0;icodelist=_ogg_malloc(n*sizeof(*c->codelist)); /* the index is a reverse index */ for(i=0;icodelist[sortindex[i]]=codes[i]; _ogg_free(codes); @@ -391,6 +397,8 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ c->dec_maxlength=s->lengthlist[i]; } + VORBIS_STACK_FREE(sortindex); + if(n==1 && c->dec_maxlength==1){ /* special case the 'single entry codebook' with a single bit fastpath table (that always returns entry 0 )in order to use diff --git a/lib/stack_alloc.h b/lib/stack_alloc.h new file mode 100644 index 000000000..37c526097 --- /dev/null +++ b/lib/stack_alloc.h @@ -0,0 +1,11 @@ +#pragma once + +#if defined(_WIN32) +#include +#define VORBIS_STACK_ALLOC(size) _malloca(size) +#define VORBIS_STACK_FREE(mem) _freea(mem) +#else +#include +#define VORBIS_STACK_ALLOC(size) alloca(size) +#define VORBIS_STACK_FREE(mem) +#endif diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c index adce8fea1..a8c80f098 100644 --- a/lib/vorbisfile.c +++ b/lib/vorbisfile.c @@ -19,6 +19,7 @@ #include #include #include +#include "stack_alloc.h" #include "vorbis/codec.h" @@ -2280,14 +2281,14 @@ int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){ hs1=ov_halfrate_p(vf1); hs2=ov_halfrate_p(vf2); - lappcm=alloca(sizeof(*lappcm)*vi1->channels); + lappcm=VORBIS_STACK_ALLOC(sizeof(*lappcm)*vi1->channels); n1=vorbis_info_blocksize(vi1,0)>>(1+hs1); n2=vorbis_info_blocksize(vi2,0)>>(1+hs2); w1=vorbis_window(&vf1->vd,0); w2=vorbis_window(&vf2->vd,0); for(i=0;ichannels;i++) - lappcm[i]=alloca(sizeof(**lappcm)*n1); + lappcm[i]=VORBIS_STACK_ALLOC(sizeof(**lappcm)*n1); _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1); @@ -2305,6 +2306,8 @@ int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){ _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2); /* done */ + for(i=vi1->channels-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); return(0); } @@ -2330,16 +2333,24 @@ static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos, from this link gets dumped, this window array continues to exist */ - lappcm=alloca(sizeof(*lappcm)*ch1); + lappcm=VORBIS_STACK_ALLOC(sizeof(*lappcm)*ch1); for(i=0;ivd,lappcm,n1); /* have lapping data; seek and prime the buffer */ ret=localseek(vf,pos); - if(ret)return ret; + if(ret) { + for(i=ch1-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); + return ret; + } ret=_ov_initprime(vf); - if(ret)return(ret); + if(ret) { + for(i=ch1-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); + return(ret); + } /* Guard against cross-link changes; they're perfectly legal */ vi=ov_info(vf,-1); @@ -2354,6 +2365,8 @@ static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos, _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); /* done */ + for(i=ch1-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); return(0); } @@ -2391,16 +2404,24 @@ static int _ov_d_seek_lap(OggVorbis_File *vf,double pos, from this link gets dumped, this window array continues to exist */ - lappcm=alloca(sizeof(*lappcm)*ch1); + lappcm=VORBIS_STACK_ALLOC(sizeof(*lappcm)*ch1); for(i=0;ivd,lappcm,n1); /* have lapping data; seek and prime the buffer */ ret=localseek(vf,pos); - if(ret)return ret; + if(ret) { + for(i=ch1-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); + return ret; + } ret=_ov_initprime(vf); - if(ret)return(ret); + if(ret) { + for(i=ch1-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); + return ret; + } /* Guard against cross-link changes; they're perfectly legal */ vi=ov_info(vf,-1); @@ -2415,6 +2436,8 @@ static int _ov_d_seek_lap(OggVorbis_File *vf,double pos, _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2); /* done */ + for(i=ch1-1;i>=0;i--)VORBIS_STACK_FREE(lappcm[i]); + VORBIS_STACK_FREE(lappcm); return(0); } diff --git a/win32/vorbis.def b/win32/vorbis.def index 884f8f023..5e8237e07 100644 --- a/win32/vorbis.def +++ b/win32/vorbis.def @@ -1,6 +1,6 @@ ; vorbis.def ; -LIBRARY +LIBRARY vorbis EXPORTS _floor_P _mapping_P diff --git a/win32/vorbisenc.def b/win32/vorbisenc.def index 79af06440..34d7206c7 100644 --- a/win32/vorbisenc.def +++ b/win32/vorbisenc.def @@ -1,6 +1,6 @@ ; vorbisenc.def ; -LIBRARY +LIBRARY vorbisenc EXPORTS vorbis_encode_init diff --git a/win32/vorbisfile.def b/win32/vorbisfile.def index 4dc554962..3780ada18 100644 --- a/win32/vorbisfile.def +++ b/win32/vorbisfile.def @@ -1,6 +1,6 @@ ; vorbisfile.def ; -LIBRARY +LIBRARY vorbisfile EXPORTS ov_clear ov_open