Yalantis/uCrop · error · CImgInstanceException
haar(): Sub-image height %u is not even.
Error message
haar(): Sub-image height %u is not even.
What it means
CImg::haar() performing the single-scale Haar transform along the Y axis requires the sub-image height (h = _height/2) to be even or equal to 1; otherwise the pairwise splitting of rows cannot proceed and it throws CImgInstanceException.
Solutions
- Pad or resize the height to a power of two before the transform.
- Choose an axis ('x' or 'z') whose dimension satisfies the evenness constraint if the data allows.
- Use the multi-scale form (nb_scales>1) if appropriate for your sizes.
- Crop to a size where height/2 is even or 1.
Example fix
// before
CImg<> out = img.get_haar('y', false, 1); // height 6 -> h=3, odd
// after
CImg<> padded = img.get_resize(img.width(), 8);
CImg<> out = padded.get_haar('y', false, 1); Defensive patterns
Strategy: validation
Validate before calling
if (unsigned h = img.height()/2; (h % 2) && h != 1) img = img.get_resize(img.width(), nextPow2(img.height()));
Type guard
bool haarYOk(const CImg<T>& img) {
unsigned h = img.height()/2;
return h == 0 || !(h % 2) || h == 1;
} Try / catch
try {
res = img.get_haar('y', invert, nb_scales);
} catch (const CImgInstanceException& e) {
res = img.get_resize(img.width(), pow2ceil(img.height())).get_haar('y', invert, nb_scales);
} Prevention
- Keep heights at powers of two for wavelet pipelines.
- Crop consistently across all dimensions, not just one axis.
- Validate height/2 evenness in unit tests for your image sizes.
When it happens
Trigger: Calling img.get_haar('y', invert, 1) when height/2 is odd and >1 — e.g. height of 6, 10, 14, 22.
Common situations: Images with non-power-of-two heights (cropped photos, sensor frames), multichannel volume processing where depth/slice count is odd, mixing transforms across axes where only one dimension is a power of two.
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
- haar(): Sub-image width %u is not even.
- blur_anisotropic(): Invalid specified diffusion tensor…
- blur_bilateral(): Invalid size for specified guide image…
- blur_guided(): Invalid size for specified guide image…
- blur_patch(): Invalid size for specified guide image…
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/5f676f6380606e8a.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:47415
for (unsigned int x = 0, xw = w, x2 = 0; x<w; ++x, ++xw) {
const Tfloat val0 = (Tfloat)(*this)(x,y,z,c), val1 = (Tfloat)(*this)(xw,y,z,c);
res(x2++,y,z,c) = (val0 - val1)/sqrt2;
res(x2++,y,z,c) = (val0 + val1)/sqrt2;
}
} else cimg_forYZC(*this,y,z,c) { // Direct transform along X
for (unsigned int x = 0, xw = w, x2 = 0; x<w; ++x, ++xw) {
const Tfloat val0 = (Tfloat)(*this)(x2++,y,z,c), val1 = (Tfloat)(*this)(x2++,y,z,c);
res(x,y,z,c) = (val0 + val1)/sqrt2;
res(xw,y,z,c) = (val1 - val0)/sqrt2;
}
}
} else return *this;
} break;
case 'y' : {
const unsigned int h = _height/2;
if (h) {
if ((h%2) && h!=1)
throw CImgInstanceException(_cimg_instance
"haar(): Sub-image height %u is not even.",
cimg_instance,
h);
res.assign(_width,_height,_depth,_spectrum);
if (invert) cimg_forXZC(*this,x,z,c) { // Inverse transform along Y
for (unsigned int y = 0, yh = h, y2 = 0; y<h; ++y, ++yh) {
const Tfloat val0 = (Tfloat)(*this)(x,y,z,c), val1 = (Tfloat)(*this)(x,yh,z,c);
res(x,y2++,z,c) = (val0 - val1)/sqrt2;
res(x,y2++,z,c) = (val0 + val1)/sqrt2;
}
} else cimg_forXZC(*this,x,z,c) {
for (unsigned int y = 0, yh = h, y2 = 0; y<h; ++y, ++yh) { // Direct transform along Y
const Tfloat val0 = (Tfloat)(*this)(x,y2++,z,c), val1 = (Tfloat)(*this)(x,y2++,z,c);
res(x,y,z,c) = (val0 + val1)/sqrt2;
res(x,yh,z,c) = (val1 - val0)/sqrt2;
}
}View on GitHub (pinned to f788b534b4)