mirror of
https://github.com/mborgerding/kissfft.git
synced 2025-05-27 21:20:27 -04:00
Merge pull request #45 from kpawlak/task-logging-and-check
Logging improvements and buffers security
This commit is contained in:
commit
f0a47de6aa
@ -15,10 +15,11 @@
|
|||||||
#define _kiss_fft_guts_h
|
#define _kiss_fft_guts_h
|
||||||
|
|
||||||
#include "kiss_fft.h"
|
#include "kiss_fft.h"
|
||||||
|
#include "kiss_fft_log.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#define MAXFACTORS 32
|
#define MAXFACTORS 32
|
||||||
/* e.g. an fft of length 128 has 4 factors
|
/* e.g. an fft of length 128 has 4 factors
|
||||||
as far as kissfft is concerned
|
as far as kissfft is concerned
|
||||||
4*4*4*2
|
4*4*4*2
|
||||||
*/
|
*/
|
||||||
@ -56,7 +57,7 @@ struct kiss_fft_state{
|
|||||||
#if defined(CHECK_OVERFLOW)
|
#if defined(CHECK_OVERFLOW)
|
||||||
# define CHECK_OVERFLOW_OP(a,op,b) \
|
# define CHECK_OVERFLOW_OP(a,op,b) \
|
||||||
if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
|
if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
|
||||||
fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
|
KISS_FFT_WARNING("overflow (%d " #op" %d) = %ld", (a),(b),(SAMPPROD)(a) op (SAMPPROD)(b)); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -146,17 +147,17 @@ struct kiss_fft_state{
|
|||||||
|
|
||||||
/* a debugging function */
|
/* a debugging function */
|
||||||
#define pcpx(c)\
|
#define pcpx(c)\
|
||||||
fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
|
KISS_FFT_DEBUG("%g + %gi\n",(double)((c)->r),(double)((c)->i))
|
||||||
|
|
||||||
|
|
||||||
#ifdef KISS_FFT_USE_ALLOCA
|
#ifdef KISS_FFT_USE_ALLOCA
|
||||||
// define this to allow use of alloca instead of malloc for temporary buffers
|
// define this to allow use of alloca instead of malloc for temporary buffers
|
||||||
// Temporary buffers are used in two case:
|
// Temporary buffers are used in two case:
|
||||||
// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
|
// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
|
||||||
// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
|
// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
|
#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
|
||||||
#define KISS_FFT_TMP_FREE(ptr)
|
#define KISS_FFT_TMP_FREE(ptr)
|
||||||
#else
|
#else
|
||||||
#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
|
#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
|
||||||
#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
|
#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
|
||||||
|
36
kiss_fft.c
36
kiss_fft.c
@ -203,6 +203,10 @@ static void kf_bfly_generic(
|
|||||||
int Norig = st->nfft;
|
int Norig = st->nfft;
|
||||||
|
|
||||||
kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
|
kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
|
||||||
|
if (scratch == NULL){
|
||||||
|
KISS_FFT_ERROR("Memory allocation failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for ( u=0; u<m; ++u ) {
|
for ( u=0; u<m; ++u ) {
|
||||||
k=u;
|
k=u;
|
||||||
@ -244,7 +248,7 @@ void kf_work(
|
|||||||
const kiss_fft_cpx * Fout_end = Fout + p*m;
|
const kiss_fft_cpx * Fout_end = Fout + p*m;
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
// use openmp extensions at the
|
// use openmp extensions at the
|
||||||
// top-level (not recursive)
|
// top-level (not recursive)
|
||||||
if (fstride==1 && p<=5 && m!=1)
|
if (fstride==1 && p<=5 && m!=1)
|
||||||
{
|
{
|
||||||
@ -252,15 +256,15 @@ void kf_work(
|
|||||||
|
|
||||||
// execute the p different work units in different threads
|
// execute the p different work units in different threads
|
||||||
# pragma omp parallel for
|
# pragma omp parallel for
|
||||||
for (k=0;k<p;++k)
|
for (k=0;k<p;++k)
|
||||||
kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
|
kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
|
||||||
// all threads have joined by this point
|
// all threads have joined by this point
|
||||||
|
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 2: kf_bfly2(Fout,fstride,st,m); break;
|
case 2: kf_bfly2(Fout,fstride,st,m); break;
|
||||||
case 3: kf_bfly3(Fout,fstride,st,m); break;
|
case 3: kf_bfly3(Fout,fstride,st,m); break;
|
||||||
case 4: kf_bfly4(Fout,fstride,st,m); break;
|
case 4: kf_bfly4(Fout,fstride,st,m); break;
|
||||||
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
||||||
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -276,7 +280,7 @@ void kf_work(
|
|||||||
do{
|
do{
|
||||||
// recursive call:
|
// recursive call:
|
||||||
// DFT of size m*p performed by doing
|
// DFT of size m*p performed by doing
|
||||||
// p instances of smaller DFTs of size m,
|
// p instances of smaller DFTs of size m,
|
||||||
// each one takes a decimated version of the input
|
// each one takes a decimated version of the input
|
||||||
kf_work( Fout , f, fstride*p, in_stride, factors,st);
|
kf_work( Fout , f, fstride*p, in_stride, factors,st);
|
||||||
f += fstride*in_stride;
|
f += fstride*in_stride;
|
||||||
@ -285,21 +289,21 @@ void kf_work(
|
|||||||
|
|
||||||
Fout=Fout_beg;
|
Fout=Fout_beg;
|
||||||
|
|
||||||
// recombine the p smaller DFTs
|
// recombine the p smaller DFTs
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case 2: kf_bfly2(Fout,fstride,st,m); break;
|
case 2: kf_bfly2(Fout,fstride,st,m); break;
|
||||||
case 3: kf_bfly3(Fout,fstride,st,m); break;
|
case 3: kf_bfly3(Fout,fstride,st,m); break;
|
||||||
case 4: kf_bfly4(Fout,fstride,st,m); break;
|
case 4: kf_bfly4(Fout,fstride,st,m); break;
|
||||||
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
case 5: kf_bfly5(Fout,fstride,st,m); break;
|
||||||
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
default: kf_bfly_generic(Fout,fstride,st,m,p); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* facbuf is populated by p1,m1,p2,m2, ...
|
/* facbuf is populated by p1,m1,p2,m2, ...
|
||||||
where
|
where
|
||||||
p[i] * m[i] = m[i-1]
|
p[i] * m[i] = m[i-1]
|
||||||
m0 = n */
|
m0 = n */
|
||||||
static
|
static
|
||||||
void kf_factor(int n,int * facbuf)
|
void kf_factor(int n,int * facbuf)
|
||||||
{
|
{
|
||||||
int p=4;
|
int p=4;
|
||||||
@ -369,7 +373,19 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,
|
|||||||
if (fin == fout) {
|
if (fin == fout) {
|
||||||
//NOTE: this is not really an in-place FFT algorithm.
|
//NOTE: this is not really an in-place FFT algorithm.
|
||||||
//It just performs an out-of-place FFT into a temp buffer
|
//It just performs an out-of-place FFT into a temp buffer
|
||||||
|
if (fout == NULL){
|
||||||
|
KISS_FFT_ERROR("fout buffer NULL.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
|
kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
|
||||||
|
if (tmpbuf == NULL){
|
||||||
|
KISS_FFT_ERROR("Memory allocation error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
|
||||||
memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
|
memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
|
||||||
KISS_FFT_TMP_FREE(tmpbuf);
|
KISS_FFT_TMP_FREE(tmpbuf);
|
||||||
|
36
kiss_fft_log.h
Normal file
36
kiss_fft_log.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
|
||||||
|
* This file is part of KISS FFT - https://github.com/mborgerding/kissfft
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
* See COPYING file for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef kiss_fft_log_h
|
||||||
|
#define kiss_fft_log_h
|
||||||
|
|
||||||
|
#define ERROR 1
|
||||||
|
#define WARNING 2
|
||||||
|
#define INFO 3
|
||||||
|
#define DEBUG 4
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
|
||||||
|
#if defined(NDEBUG)
|
||||||
|
# define KISS_FFT_LOG_MSG(severity, ...) ((void)0)
|
||||||
|
#else
|
||||||
|
# define KISS_FFT_LOG_MSG(severity, ...) \
|
||||||
|
fprintf(stderr, "[" #severity "] " __FILE__ ":" TOSTRING(__LINE__) " "); \
|
||||||
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
|
fprintf(stderr, "\n")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KISS_FFT_ERROR(...) KISS_FFT_LOG_MSG(ERROR, __VA_ARGS__)
|
||||||
|
#define KISS_FFT_WARNING(...) KISS_FFT_LOG_MSG(WARNING, __VA_ARGS__)
|
||||||
|
#define KISS_FFT_INFO(...) KISS_FFT_LOG_MSG(INFO, __VA_ARGS__)
|
||||||
|
#define KISS_FFT_DEBUG(...) KISS_FFT_LOG_MSG(DEBUG, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* kiss_fft_log_h */
|
@ -27,7 +27,7 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme
|
|||||||
size_t subsize = 0, memneeded;
|
size_t subsize = 0, memneeded;
|
||||||
|
|
||||||
if (nfft & 1) {
|
if (nfft & 1) {
|
||||||
fprintf(stderr,"Real FFT optimization must be even.\n");
|
KISS_FFT_ERROR("Real FFT optimization must be even.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
nfft >>= 1;
|
nfft >>= 1;
|
||||||
@ -67,7 +67,7 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
|
|||||||
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
|
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
|
||||||
|
|
||||||
if ( st->substate->inverse) {
|
if ( st->substate->inverse) {
|
||||||
fprintf(stderr,"kiss fft usage error: improper alloc\n");
|
KISS_FFT_ERROR("kiss fft usage error: improper alloc");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,12 +79,12 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
|
|||||||
* contains the sum of the even-numbered elements of the input time sequence
|
* contains the sum of the even-numbered elements of the input time sequence
|
||||||
* The imag part is the sum of the odd-numbered elements
|
* The imag part is the sum of the odd-numbered elements
|
||||||
*
|
*
|
||||||
* The sum of tdc.r and tdc.i is the sum of the input time sequence.
|
* The sum of tdc.r and tdc.i is the sum of the input time sequence.
|
||||||
* yielding DC of input time sequence
|
* yielding DC of input time sequence
|
||||||
* The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
|
* The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
|
||||||
* yielding Nyquist bin of input time sequence
|
* yielding Nyquist bin of input time sequence
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tdc.r = st->tmpbuf[0].r;
|
tdc.r = st->tmpbuf[0].r;
|
||||||
tdc.i = st->tmpbuf[0].i;
|
tdc.i = st->tmpbuf[0].i;
|
||||||
C_FIXDIV(tdc,2);
|
C_FIXDIV(tdc,2);
|
||||||
@ -92,14 +92,14 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
|
|||||||
CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
|
CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
|
||||||
freqdata[0].r = tdc.r + tdc.i;
|
freqdata[0].r = tdc.r + tdc.i;
|
||||||
freqdata[ncfft].r = tdc.r - tdc.i;
|
freqdata[ncfft].r = tdc.r - tdc.i;
|
||||||
#ifdef USE_SIMD
|
#ifdef USE_SIMD
|
||||||
freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
|
freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
|
||||||
#else
|
#else
|
||||||
freqdata[ncfft].i = freqdata[0].i = 0;
|
freqdata[ncfft].i = freqdata[0].i = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for ( k=1;k <= ncfft/2 ; ++k ) {
|
for ( k=1;k <= ncfft/2 ; ++k ) {
|
||||||
fpk = st->tmpbuf[k];
|
fpk = st->tmpbuf[k];
|
||||||
fpnk.r = st->tmpbuf[ncfft-k].r;
|
fpnk.r = st->tmpbuf[ncfft-k].r;
|
||||||
fpnk.i = - st->tmpbuf[ncfft-k].i;
|
fpnk.i = - st->tmpbuf[ncfft-k].i;
|
||||||
C_FIXDIV(fpk,2);
|
C_FIXDIV(fpk,2);
|
||||||
@ -122,7 +122,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *t
|
|||||||
int k, ncfft;
|
int k, ncfft;
|
||||||
|
|
||||||
if (st->substate->inverse == 0) {
|
if (st->substate->inverse == 0) {
|
||||||
fprintf (stderr, "kiss fft usage error: improper alloc\n");
|
KISS_FFT_ERROR("kiss fft usage error: improper alloc");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *t
|
|||||||
C_MUL (fok, tmp, st->super_twiddles[k-1]);
|
C_MUL (fok, tmp, st->super_twiddles[k-1]);
|
||||||
C_ADD (st->tmpbuf[k], fek, fok);
|
C_ADD (st->tmpbuf[k], fek, fok);
|
||||||
C_SUB (st->tmpbuf[ncfft - k], fek, fok);
|
C_SUB (st->tmpbuf[ncfft - k], fek, fok);
|
||||||
#ifdef USE_SIMD
|
#ifdef USE_SIMD
|
||||||
st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
|
st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
|
||||||
#else
|
#else
|
||||||
st->tmpbuf[ncfft - k].i *= -1;
|
st->tmpbuf[ncfft - k].i *= -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user