Yalantis/uCrop · error · CImgInstanceException
CImgList< >::FFT(): Specified real and imaginary parts…
Error message
CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) have non 2^N dimension along the Y-axis.
What it means
Same built-in radix-2 constraint as the X-axis case, but applied to real._height: when FFT() computes along the Y-axis (axis='y') without FFTW3, the height must be 1 or a power of 2, otherwise this CImgInstanceException is thrown. The check is ((N-1)&N) && N!=1 with N=real._height.
Solutions
- Pad/crop the image height to the next power of 2 before the FFT.
- Compile with cimg_use_fftw3 to lift the power-of-two restriction.
- Resize the image (CImg::resize) to power-of-two dimensions.
- Pre-check height: if ((h & (h-1)) != 0) pad first.
Example fix
// before img.FFT(true, false, 'y'); // height 1080 not 2^N // after const unsigned int h2 = 1; while (h2 < img.height()) h2 <<= 1; img.get_resize(img.width(), h2, -100, -100, 0).FFT(true, false, 'y');
Defensive patterns
Strategy: validation
Validate before calling
unsigned int h = img.height(); bool isPow2 = h == 1 || ((h & (h - 1)) == 0); if (!isPow2) img.resize(img.width(), nextPow2(h), img.depth(), img.spectrum(), 0);
Type guard
bool isPowerOfTwo(unsigned int n) { return n == 1 || (n && !(n & (n - 1))); } Try / catch
try { img.FFT(is_inverse, false, 'y'); }
catch (CImgInstanceException& e) { /* pad height and retry */ } Prevention
- Check image height (e.g. 1080 is not 2^N) before Y-axis FFT without FFTW3
- Standardize pipeline resolutions to power-of-two heights
- Compile with cimg_use_fftw3 to avoid the restriction entirely
When it happens
Trigger: Calling FFT() with axis='y' (or CImgList FFT along Y) on an image whose _height is not a power of two, in a build without cimg_use_fftw3.
Common situations: Images sized to display resolution (e.g. 1920x1080 -> height 1080 not 2^N), video frames, or scanning/sensor rows counts that are arbitrary.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- CImgList< >::FFT(): Specified real and imaginary parts…
- CImgList< >::FFT(): Specified real and imaginary parts…
- CImg< >::FFT(): Specified real part is empty.
- CImg< >::FFT(): Specified real part (%u,%u,%u,%u,%p) and…
- CImgList< >::FFT(): Empty specified real part.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/756ddaa0ab6783c0.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:47826
T &ir = real(j,y,z,c), &ii = imag(j,y,z,c), &nir = real(nj,y,z,c), &nii = imag(nj,y,z,c);
const float tmpr = (float)(wr*nir - wi*nii), tmpi = (float)(wr*nii + wi*nir);
nir = (T)(ir - tmpr);
nii = (T)(ii - tmpi);
ir+=(T)tmpr;
ii+=(T)tmpi;
}
const float nwr = wr*ca-wi*sa;
wi = wi*ca + wr*sa;
wr = nwr;
}
}
}
if (is_inverse) { real/=N; imag/=N; }
} break;
case 'y' : { // Fourier along Y, using built-in functions
const unsigned int N = real._height, N2 = N>>1;
if (((N - 1)&N) && N!=1)
throw CImgInstanceException("CImgList<%s>::FFT(): Specified real and imaginary parts (%u,%u,%u,%u) "
"have non 2^N dimension along the Y-axis.",
pixel_type(),
real._width,real._height,real._depth,real._spectrum);
for (unsigned int i = 0, j = 0; i<N2; ++i) {
if (j>i) cimg_forXZC(real,x,z,c) {
cimg::swap(real(x,i,z,c),real(x,j,z,c));
cimg::swap(imag(x,i,z,c),imag(x,j,z,c));
if (j<N2) {
const unsigned int ri = N - 1 - i, rj = N - 1 - j;
cimg::swap(real(x,ri,z,c),real(x,rj,z,c));
cimg::swap(imag(x,ri,z,c),imag(x,rj,z,c));
}
}
for (unsigned int m = N, n = N2; (j+=n)>=m; j-=m, m = n, n>>=1) {}
}
for (unsigned int delta = 2; delta<=N; delta<<=1) {
const unsigned int delta2 = (delta>>1);View on GitHub (pinned to f788b534b4)