Yalantis/uCrop · error · CImgArgumentException
haar(): Invalid specified axis '%c' (should be { x | y | z }
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.
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)
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<%s>: Function 'polygon(
- "[" cimg_appname "_math_parser] CImg<%s>: Function 'polygon(
- invert(): Specified lambda (%g) should be >=0.
- sort(): Invalid specified axis '%c' (should be { x | y | z |
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/ece2c6ff76b25e46.
Report an issue: GitHub.