Yalantis/uCrop · error · CImgArgumentException
[cimg_appname_math_parser] CImg<%s>::%s: %s: Cannot crop emp
Error message
[cimg_appname_math_parser] CImg<%s>::%s: %s: Cannot crop empty image when some xyzc-coordinates are unspecified, in expression '%s'.
What it means
CImg's math parser (used by expressions like fill, crop, or index-based access) throws this when an expression attempts to crop an image whose instance is empty (zero dimensions) while some x/y/z/c coordinates are left unspecified, so defaults would have to be taken from the image's own dimensions. The parser checks `if (!img)` before resolving unspecified coordinates and aborts with CImgArgumentException rather than producing an undefined crop. It is a defensive guard: an empty image has no geometry to substitute for omitted coordinates.
Source
Thrown at ucrop/src/main/jni/CImg.h:20688
opcode[6] = (ulongT)mem[opcode[6]];
}
if (opcode[7]!=(ulongT)~0U) {
_cimg_mp_check_const_scalar((unsigned int)opcode[7],arg1 + 3,3);
opcode[7] = (ulongT)mem[opcode[7]];
}
_cimg_mp_check_type((unsigned int)opcode[8],arg1 + 4,1,0);
if (opcode[4]==(ulongT)~0U || opcode[5]==(ulongT)~0U ||
opcode[6]==(ulongT)~0U || opcode[7]==(ulongT)~0U) {
p2 = 0;
if (p1!=~0U) {
_cimg_mp_check_const_scalar(p1,1,1);
p2 = (unsigned int)cimg::mod((int)mem[p1],imglist.width());
}
const CImg<T> &img = p1!=~0U?imglist[p2]:imgin;
if (!img) {
_cimg_mp_strerr;
throw CImgArgumentException("[" cimg_appname "_math_parser] "
"CImg<%s>::%s: %s: Cannot crop empty image when "
"some xyzc-coordinates are unspecified, in expression '%s'.",
pixel_type(),_cimg_mp_calling_function,s_op,s0);
}
if (opcode[4]==(ulongT)~0U) opcode[4] = (ulongT)img._width;
if (opcode[5]==(ulongT)~0U) opcode[5] = (ulongT)img._height;
if (opcode[6]==(ulongT)~0U) opcode[6] = (ulongT)img._depth;
if (opcode[7]==(ulongT)~0U) opcode[7] = (ulongT)img._spectrum;
}
pos = vector((unsigned int)(opcode[4]*opcode[5]*opcode[6]*opcode[7]));
CImg<ulongT>::vector((ulongT)mp_image_crop,
pos,p1, // 1-2: res,#ind
*opcode,opcode[1],opcode[2],opcode[3], // 3-6: x,y,z,c
opcode[4],opcode[5],opcode[6],opcode[7], // 7-10: dx,dy,dz,dc
opcode[8]).move_to(code); // 11: boundary conditions
} else { // Vector cropView on GitHub (pinned to f788b534b4)
Solutions
- Check that the target image is non-empty before evaluating the expression: `if (img && !img.is_empty()) ...`
- Verify the image-list index p2 resolves to the intended, populated image (print imglist.size() and img.width()).
- Specify all four x/y/z/c coordinates explicitly so the parser does not need to default them from the empty image's geometry.
- Debug upstream steps in the expression pipeline that emptied the image (failed load, crop with zero extent).
Example fix
// before img.crop(10,10); // img may be empty -> parser throws // after if (!img.is_empty()) img.crop(10,10, x, y, z, c); // or guard upstream load
Defensive patterns
Strategy: validation
Validate before calling
// before evaluating the expression
if (img.is_empty()) throw std::runtime_error("source image is empty; skip crop expression");
// CImg API
cimg_for(imglist, ptr, T) if (ptr->is_empty()) ... handle ...; Type guard
template<typename T>
bool is_cropable(const CImg<T>& im) { return !im.is_empty(); } Try / catch
try {
img.crop(x, y, z, c);
} catch (const CImgArgumentException& e) {
// empty-image crop guard: log and fall back to original image
result = img;
} Prevention
- Always check is_empty() after loading/producing an image before further processing
- Validate image-list slots are populated before indexing them in expressions
- Pass explicit x/y/z/c coordinates instead of relying on defaults
- Fail fast when an upstream step yields a zero-size image
When it happens
Trigger: Calling crop() inside a math expression (e.g. `crop(...)` opcode in an expression like `i(x,y)`-style pipelines or `crop(ind,...)`) on image slot 0 or imglist[p2] that is empty, while omitting one or more of the x/y/z/c arguments so the parser tries to default them from img._width/_height etc. Occurs when imglist.width()>0 but the selected image is a default-constructed empty CImg, or imgin is empty.
Common situations: A G'MIC/CImg filter chain where an earlier processing step produced a zero-size image (e.g. a failed threshold or resize to 0); indexing the wrong image list slot whose entry was never assigned; loading an image from a missing/failed source and continuing to crop without checking.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- crop(): Empty instance.
- display(): Empty specified image.
- render(): Empty specified image.
- at(): Empty instance.
- atX(): Empty instance.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/f10edf82de4804e8.
Report an issue: GitHub.