{"record":{"id":"860cd12e0561d34c","repo":"Yalantis/uCrop","slug":"cimg-s-fft-specified-real-part-u-u-u-u","errorCode":null,"errorMessage":"CImg<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and imaginary part (%u,%u,%u,%u,%p) have different dimensions.","messagePattern":"CImg<(.+?)>::FFT\\(\\): Specified real part \\(%u,%u,%u,%u,%p\\) and imaginary part \\(%u,%u,%u,%u,%p\\) have different dimensions\\.","errorType":"exception","errorClass":"CImgInstanceException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":47660,"sourceCode":"      CImg<Tfloat>::FFT(res[0],res[1],is_inverse);\n      return res;\n    }\n\n    //! Compute 1D Fast Fourier Transform, along a specified axis.\n    /**\n       \\param[in,out] real Real part of the pixel values.\n       \\param[in,out] imag Imaginary part of the pixel values.\n       \\param axis Axis along which the FFT is computed.\n       \\param is_inverse Tells if the forward (\\c false) or inverse (\\c true) FFT is computed.\n    **/\n    static void FFT(CImg<T>& real, CImg<T>& imag, const char axis, const bool is_inverse=false,\n                    const unsigned int nb_threads=0) {\n      if (!real)\n        throw CImgInstanceException(\"CImg<%s>::FFT(): Specified real part is empty.\",\n                                    pixel_type());\n      if (!imag) imag.assign(real._width,real._height,real._depth,real._spectrum,(T)0);\n      if (!real.is_sameXYZC(imag))\n        throw CImgInstanceException(\"CImg<%s>::FFT(): Specified real part (%u,%u,%u,%u,%p) and \"\n                                    \"imaginary part (%u,%u,%u,%u,%p) have different dimensions.\",\n                                    pixel_type(),\n                                    real._width,real._height,real._depth,real._spectrum,real._data,\n                                    imag._width,imag._height,imag._depth,imag._spectrum,imag._data);\n      const char _axis = cimg::lowercase(axis);\n      if (_axis!='x' && _axis!='y' && _axis!='z')\n        throw CImgArgumentException(\"CImgList<%s>::FFT(): Invalid specified axis '%c' for real and imaginary parts \"\n                                    \"(%u,%u,%u,%u) \"\n                                    \"(should be { x | y | z }).\",\n                                    pixel_type(),axis,\n                                    real._width,real._height,real._depth,real._spectrum);\n      cimg::unused(nb_threads);\n#ifdef cimg_use_fftw3\n      cimg::mutex(12);\n#ifndef cimg_use_fftw3_singlethread\n      fftw_plan_with_nthreads(nb_threads?nb_threads:cimg::nb_cpus());\n#endif\n      fftw_complex *data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*real._width*real._height*real._depth);","sourceCodeStart":47642,"sourceCodeEnd":47678,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L47642-L47678","documentation":"CImg::FFT(real, imag, axis, is_inverse) requires the imaginary buffer to have the same width, height, depth and spectrum as the real buffer. If imag was empty it is auto-sized to real, but if imag is non-empty with different XYZC dimensions, is_sameXYZC fails and CImgInstanceException is thrown with both images' dimensions and data pointers in the message.","triggerScenarios":"Reusing a persistent `imag` buffer from a previous FFT of a differently sized image; calling FFT with real and imag allocated at different resolutions; spectrum mismatch (e.g. real is 3-channel, imag is 1-channel).","commonSituations":"Looping over frames of varying sizes while reusing scratch FFT buffers; after an image resize only the real part was resized; passing results from two different pipelines.","solutions":["Call real.is_sameXYZC(imag) (or compare all four dims) before FFT.","Let FFT allocate the imaginary part: pass an empty CImg (imag.assign(); or default-constructed) so it auto-fills with zeros.","Explicitly reassign imag to match: imag.assign(real._width, real._height, real._depth, real._spectrum, 0).","In loops, re-create or re-assign scratch buffers whenever the input size changes."],"exampleFix":"// before\nCImg<float> real = imgA, imag = imgB; // imgB has different dims\nCImg<float>::FFT(real, imag, 'x'); // dimension mismatch -> throws\n// after\nCImg<float> real = imgA;\nCImg<float> imag; // empty: FFT auto-assigns to real's dims\nCImg<float>::FFT(real, imag, 'x');","handlingStrategy":"validation","validationCode":"if (!real.is_sameXYZC(imag)) imag.assign(real._width, real._height, real._depth, real._spectrum, (T)0);","typeGuard":"bool fftBuffersCompatible(const CImg<T>& real, const CImg<T>& imag) {\n  return real.is_sameXYZC(imag);\n}","tryCatchPattern":"try {\n  CImg<T>::FFT(real, imag, axis);\n} catch (const CImgInstanceException& e) {\n  imag.assign(real._width, real._height, real._depth, real._spectrum, (T)0);\n  CImg<T>::FFT(real, imag, axis);\n}","preventionTips":["Pass an empty CImg as imag and let FFT allocate it.","Re-assign scratch buffers whenever input sizes change in loops.","Keep real and imag produced by the same pipeline stage."],"tags":["cimg","fft","dimension-mismatch","buffer-reuse"],"backgroundTag":"shape-mismatch","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}