Yalantis/uCrop · critical · CImgInstanceException

CImgList<%s>::FFT(): Failed to allocate memory (%s) for comp

Error message

CImgList<%s>::FFT(): Failed to allocate memory (%s) for computing FFT of image (%u,%u,%u,%u).

What it means

Like error 291 but on the generic FFT path: with FFTW3 enabled, CImg::FFT allocates fftw_complex storage for the whole width*height*depth volume. If fftw_malloc returns NULL the allocation size (via cimg::strbuffersize) and image dimensions are reported in this CImgInstanceException. It means the process ran out of memory for the temporary FFT buffer.

Source

Thrown at ucrop/src/main/jni/CImg.h:47947

      if (!real)
        throw CImgInstanceException("CImgList<%s>::FFT(): Empty specified real part.",
                                    pixel_type());
      if (!imag) imag.assign(real._width,real._height,real._depth,real._spectrum,(T)0);
      if (!real.is_sameXYZC(imag))
        throw CImgInstanceException("CImgList<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and "
                                    "imaginary part (%u,%u,%u,%u,%p) have different dimensions.",
                                    pixel_type(),
                                    real._width,real._height,real._depth,real._spectrum,real._data,
                                    imag._width,imag._height,imag._depth,imag._spectrum,imag._data);
      cimg::unused(nb_threads);
#ifdef cimg_use_fftw3
      cimg::mutex(12);
#ifndef cimg_use_fftw3_singlethread
      fftw_plan_with_nthreads(nb_threads?nb_threads:cimg::nb_cpus());
#endif
      fftw_complex *data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*real._width*real._height*real._depth);
      if (!data_in)
        throw CImgInstanceException("CImgList<%s>::FFT(): Failed to allocate memory (%s) "
                                    "for computing FFT of image (%u,%u,%u,%u).",
                                    pixel_type(),
                                    cimg::strbuffersize(sizeof(fftw_complex)*real._width*
                                                        real._height*real._depth*real._spectrum),
                                    real._width,real._height,real._depth,real._spectrum);
      double *const ptrf = (double*)data_in;
      fftw_plan data_plan =
        real._depth>1?fftw_plan_dft_3d(real._depth,real._height,real._width,data_in,data_in,
                                       is_inverse?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE):
        real._height>1?fftw_plan_dft_2d(real._height,real._width,data_in,data_in,
                                        is_inverse?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE):
        fftw_plan_dft_1d(real._width,data_in,data_in,
                         is_inverse?FFTW_BACKWARD:FFTW_FORWARD,FFTW_ESTIMATE);
      cimg_forC(real,c) {
        CImg<T> realc = real.get_shared_channel(c), imagc = imag.get_shared_channel(c);
        cimg_pragma_openmp(parallel for cimg_openmp_if_size(real.width()*real.height()*real.depth(),125000))
        cimg_rofoff(realc,i) { const ulongT i2 = 2*i; ptrf[i2] = (double)realc[i]; ptrf[i2 + 1] = (double)imagc[i]; }
        fftw_execute(data_plan);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Reduce image/volume size (downsample, crop, tile) before FFT.
  2. Raise the memory limit (64-bit build, larger container/cgroup limit, more RAM).
  3. Process in tiles/slabs along one axis and stitch results.
  4. Free cached images/other buffers before the FFT to reduce peak usage.
Defensive patterns

Strategy: validation

Validate before calling

size_t bytes = sizeof(fftw_complex) * (size_t)img.width()*img.height()*img.depth();
if (bytes > memBudget()) { /* tile or downsample first */ }

Try / catch

try { img.FFT(real, imag); }
catch (CImgInstanceException& e) { std::cerr << "Out of memory for FFT (" << e.what() << ")"; /* fallback: tiled FFT */ }

Prevention

When it happens

Trigger: Calling CImg<T>::FFT(real, imag) or CImgList::FFT() compiled with cimg_use_fftw3 on a volume where width*height*depth*16 bytes exceeds available heap.

Common situations: Large 3D volumes or huge 2D images (e.g. gigapixel scans), 32-bit builds limited to ~2-3 GB, containers with tight memory limits, or heavy fragmentation from prior large allocations.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/ab4ddbb8c03ab1e4. Report an issue: GitHub.