// Wrapper around FFTW3 that computes the real-valued inverse Fourier transform // of a complex-valued frequantial image. // The input data must be hermitic. static void ifft_2dfloat(float *ifx, fftwf_complex *fx, int w, int h) { fftwf_complex *a = fftwf_xmalloc(w*h*sizeof*a); fftwf_complex *b = fftwf_xmalloc(w*h*sizeof*b); //fprintf(stderr, "planning...\n"); evoke_wisdom(); fftwf_plan p = fftwf_plan_dft_2d(h, w, a, b, FFTW_BACKWARD, FFTW_ESTIMATE); bequeath_wisdom(); //fprintf(stderr, "...planned!\n"); FORI(w*h) a[i] = fx[i]; fftwf_execute(p); float scale = 1.0/(w*h); FORI(w*h) { fftwf_complex z = b[i] * scale; ifx[i] = crealf(z); if (FIWARN() > 0) { if (cimagf(z) > 0.001) fail("z is not real {cimagf(z)=%g} (set FIWARN=0 to run anyway)", cimagf(z)); //assert(cimagf(z) < 0.001); } }
// wrapper around FFTW3 that computes the complex-valued Fourier transform // of a real-valued image static void fft_2dfloat(fftwf_complex *fx, float *x, int w, int h) { fftwf_complex *a = fftwf_malloc(w*h*sizeof*a); //fprintf(stderr, "planning...\n"); evoke_wisdom(); fftwf_plan p = fftwf_plan_dft_2d(h, w, a, fx, FFTW_FORWARD, FFTW_ESTIMATE); bequeath_wisdom(); //fprintf(stderr, "...planned!\n"); FORI(w*h) a[i] = x[i]; // complex assignment! fftwf_execute(p); fftwf_destroy_plan(p); fftwf_free(a); fftwf_cleanup(); }
// Wrapper around FFTW3 that computes the real-valued inverse Fourier transform // of a complex-valued frequantial image. // The input data must be hermitic. static void ifft_2dfloat(float *ifx, fftwf_complex *fx, int w, int h) { fftwf_complex *a = fftwf_malloc(w*h*sizeof*a); fftwf_complex *b = fftwf_malloc(w*h*sizeof*b); //fprintf(stderr, "planning...\n"); evoke_wisdom(); fftwf_plan p = fftwf_plan_dft_2d(h, w, a, b, FFTW_BACKWARD, FFTW_ESTIMATE); bequeath_wisdom(); //fprintf(stderr, "...planned!\n"); FORI(w*h) a[i] = fx[i]; fftwf_execute(p); float scale = 1.0/(w*h); FORI(w*h) { fftwf_complex z = b[i] * scale; ifx[i] = crealf(z); //assert(cimagf(z) < 0.001); }