Yalantis/uCrop · error · CImgInstanceException
CImg<%s>::%s() [%u]: cubic_atX_p(): Empty instance.
Error message
CImg<%s>::%s() [%u]: cubic_atX_p(): Empty instance.
What it means
cubic_atX_p() is the periodic-boundary variant of cubic X-axis cubic interpolation. Like cubic_atX(), it checks is_empty() first and throws CImgInstanceException when the image has no pixels, because interpolation is undefined on an empty buffer.
Source
Thrown at ucrop/src/main/jni/CImg.h:16373
}
//! Return clamped pixel value, using cubic interpolation and Neumann boundary conditions for the X-coordinate.
/**
Similar to cubic_atX(float,int,int,int) const, except that the return value is clamped to stay in the
min/max range of the datatype \c T.
**/
T cubic_atX_c(const float fx, const int y, const int z, const int c) const {
return cimg::type<T>::cut(cubic_atX(fx,y,z,c));
}
T _cubic_atX_c(const float fx, const int y, const int z, const int c) const {
return cimg::type<T>::cut(_cubic_atX(fx,y,z,c));
}
//! Return pixel value, using cubic interpolation and periodic boundary conditions for the X-coordinate.
Tfloat cubic_atX_p(const float fx, const int y=0, const int z=0, const int c=0) const {
if (is_empty())
throw CImgInstanceException(_cimg_instance
"cubic_atX_p(): Empty instance.",
cimg_instance);
return _cubic_atX_p(fx,y,z,c);
}
Tfloat _cubic_atX_p(const float fx, const int y=0, const int z=0, const int c=0) const {
const float
nfx = cimg::type<float>::is_nan(fx)?0:cimg::mod(fx,_width - 0.5f);
const int
x = (int)nfx;
const float
dx = nfx - x;
const int
px = cimg::mod(x - 1,width()), nx = cimg::mod(x + 1,width()), ax = cimg::mod(x + 2,width());
const Tfloat
Ip = (Tfloat)(*this)(px,y,z,c), Ic = (Tfloat)(*this)(x,y,z,c),
In = (Tfloat)(*this)(nx,y,z,c), Ia = (Tfloat)(*this)(ax,y,z,c);
return Ic + 0.5f*(dx*(-Ip + In) + dx*dx*(2*Ip - 5*Ic + 4*In - Ia) + dx*dx*dx*(-Ip + 3*Ic - 3*In + Ia));View on GitHub (pinned to f788b534b4)
Solutions
- Guard with if (!img.is_empty()) before calling cubic_atX_p().
- Validate the loaded image dimensions right after load/assign and bail out early if empty.
- Make upstream crop/resize code guarantee at least 1x1x1x1 dimensions.
- Catch CImgInstanceException around the call to fail gracefully.
Example fix
// before
CImg<unsigned char> img; // never loaded
float v = img.cubic_atX_p(1.5f);
// after
if (img && !img.is_empty()) {
float v = img.cubic_atX_p(1.5f);
} Defensive patterns
Strategy: validation
Validate before calling
if (img.is_empty()) return 0.f; // or handle float v = img.cubic_atX_p(fx, y, z, c);
Type guard
template <typename T> bool non_empty(const CImg<T>& im) { return !im.is_empty(); } Try / catch
try {
float v = img.cubic_atX_p(fx);
} catch (const CImgInstanceException& e) {
// substitute fallback value or propagate error
} Prevention
- Validate image dimensions > 0 before any periodic sampling.
- Check load() success before processing.
- In pipelines, assert non-empty images at stage boundaries.
- Avoid clear()-then-use patterns without reassignment in between.
When it happens
Trigger: Calling cubic_atX_p(fx,...) on a default-constructed CImg<T> or one with any zero dimension; passing an image whose load failed into periodic resampling/wrapping code.
Common situations: Seamless-tiling / periodic-wrapping image transforms where the source image never loaded; pipeline stages that clear() and re-assign images leaving a window where the image is empty.
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
- CImg<%s>::%s() [%u]: cubic_atX(): Empty instance.
- CImg<%s>::%s() [%u]: cubic_atXY(): Empty instance.
- CImg<%s>::%s() [%u]: cubic_atXY_p(): Empty instance.
- atXYZC(): Empty instance.
- linear_atX(): Empty instance.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/d987b6fd8336ce9d.
Report an issue: GitHub.