Yalantis/uCrop · error · CImgArgumentException
haar(): Invalid specified axis '%c
Error message
haar(): Invalid specified axis '%c' (should be { x | y | z }). What it means
In the single-scale branch of CImg::haar(), the axis argument (lowercased) is dispatched with a switch over 'x', 'y', 'z'. Any other character reaches the default case and raises CImgArgumentException, because the transform can only run along one of the three spatial axes.
Solutions
- Pass exactly 'x', 'y' or 'z' (case-insensitive) as the axis argument.
- Sanitize/validate user input to a whitelisted axis before calling.
- Clamp a dimension index to an axis: {0:'x',1:'y',2:'z'} mapping.
- Initialize the axis variable to a valid default such as 'x'.
Example fix
// before
img.get_haar('w', false, 1); // invalid axis
// after
img.get_haar('x', false, 1); Defensive patterns
Strategy: validation
Validate before calling
if (axis!='x' && axis!='y' && axis!='z') throw std::invalid_argument("haar axis must be x, y or z"); Type guard
bool isHaarAxis(char axis) {
char a = std::tolower((unsigned char)axis);
return a=='x' || a=='y' || a=='z';
} Try / catch
try {
res = img.get_haar(axis, invert, nb_scales);
} catch (const CImgArgumentException& e) {
axis = 'x'; // safe default, log the bad input
res = img.get_haar(axis, invert, nb_scales);
} Prevention
- Whitelist user-supplied axis strings to {x,y,z}.
- Never pass dimension indices or strings where a char axis is expected.
- Initialize axis variables to a valid default.
When it happens
Trigger: Calling img.get_haar(axis, invert, 1) with axis not in {'x','X','y','Y','z','Z'} — e.g. 'w' for width, '0', '\0' (uninitialized char), or a variable set from misparsed user input.
Common situations: Mapping a user-facing string ('horizontal'/'width') to an axis char incorrectly; passing the dimension index instead of a char; uninitialized or defaulted axis variables in wrapper code.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- load_yuv(): Specified chroma subsampling %u is invalid, for…
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- draw_point(): Invalid specified point set (%u,%u,%u,%u,%p).
- haar(): Sub-image height %u is not even.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/ece2c6ff76b25e46.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:47462
res.assign(_width,_height,_depth,_spectrum);
if (invert) cimg_forXYC(*this,x,y,c) { // Inverse transform along Z
for (unsigned int z = 0, zd = d, z2 = 0; z<d; ++z, ++zd) {
const Tfloat val0 = (Tfloat)(*this)(x,y,z,c), val1 = (Tfloat)(*this)(x,y,zd,c);
res(x,y,z2++,c) = (val0 - val1)/sqrt2;
res(x,y,z2++,c) = (val0 + val1)/sqrt2;
}
} else cimg_forXYC(*this,x,y,c) {
for (unsigned int z = 0, zd = d, z2 = 0; z<d; ++z, ++zd) { // Direct transform along Z
const Tfloat val0 = (Tfloat)(*this)(x,y,z2++,c), val1 = (Tfloat)(*this)(x,y,z2++,c);
res(x,y,z,c) = (val0 + val1)/sqrt2;
res(x,y,zd,c) = (val1 - val0)/sqrt2;
}
}
} else return *this;
} break;
default :
throw CImgArgumentException(_cimg_instance
"haar(): Invalid specified axis '%c' "
"(should be { x | y | z }).",
cimg_instance,
axis);
}
} else { // Multi-scale version
if (invert) {
res.assign(*this,false);
switch (cimg::lowercase(axis)) {
case 'x' : {
unsigned int w = _width;
for (unsigned int s = 1; w && s<nb_scales; ++s) w/=2;
for (w = w?w:1; w<=_width; w*=2) res.draw_image(res.get_crop(0,w - 1).get_haar('x',true,1));
} break;
case 'y' : {
unsigned int h = _width;
for (unsigned int s = 1; h && s<nb_scales; ++s) h/=2;
for (h = h?h:1; h<=_height; h*=2) res.draw_image(res.get_crop(0,0,_width - 1,h - 1).get_haar('y',true,1));View on GitHub (pinned to f788b534b4)