Yalantis/uCrop · error · CImgInstanceException

linear_atX(): Empty instance.

Error message

linear_atX(): Empty instance.

What it means

CImg<T>::linear_atX(fx,y,z,c) returns a bilinearly interpolated pixel value with Neumann boundary conditions on the X-coordinate. It throws CImgInstanceException when the image is empty, since interpolation requires an allocated pixel buffer. Y, Z and C coordinates are NOT bounds-checked, only emptiness is validated here.

Source

Thrown at ucrop/src/main/jni/CImg.h:15863

    /**
       Return a linearly-interpolated pixel value of the image instance located at (\c fx,\c y,\c z,\c c),
       or the value of the nearest pixel location in the image instance in case of out-of-bounds access along
       the X-axis.
       \param fx X-coordinate of the pixel value (float-valued).
       \param y Y-coordinate of the pixel value.
       \param z Z-coordinate of the pixel value.
       \param c C-coordinate of the pixel value.
       \note
       - Similar to linear_atX(float,int,int,int,const T) const, except that an out-of-bounds access returns
         the value of the nearest pixel in the image instance, regarding the specified X-coordinate.
       - If you know your image instance is \e not empty, you may rather use the slightly faster method
         \c _linear_atX(float,int,int,int).
       \warning
       - There is \e no boundary checking performed for the Y,Z and C-coordinates, so they must be inside image bounds.
    **/
    Tfloat linear_atX(const float fx, const int y=0, const int z=0, const int c=0) const {
      if (is_empty())
        throw CImgInstanceException(_cimg_instance
                                    "linear_atX(): Empty instance.",
                                    cimg_instance);

      return _linear_atX(fx,y,z,c);
    }

    Tfloat _linear_atX(const float fx, const int y=0, const int z=0, const int c=0) const {
      const float
        nfx = cimg::cut(fx,0.f,width() - 1.f);
      const unsigned int
        x = (unsigned int)nfx;
      const float
        dx = nfx - x;
      const unsigned int
        nx = dx>0?x + 1:x;
      const Tfloat
        Ic = (Tfloat)(*this)(x,y,z,c), In = (Tfloat)(*this)(nx,y,z,c);
      return Ic + dx*(In - Ic);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check img.is_empty() before calling linear_atX.
  2. Verify the image load succeeded and dimensions are non-zero before interpolation.
  3. Initialize the image with allocate()/assign(w,h,d,s) if it was default-constructed.
  4. Use _linear_atX() only after validating non-emptiness elsewhere for performance.

Example fix

// before
CImg<float> img;
float v = img.linear_atX(3.5f, y);
// after
if (!img.is_empty()) {
  float v = img.linear_atX(3.5f, y);
}
Defensive patterns

Strategy: validation

Validate before calling

if (img.is_empty()) throw std::runtime_error("image not initialized"); float v = img.linear_atX(fx, y);

Type guard

inline bool samplable(const cimg_library::CImg<T>& img) { return !img.is_empty(); }

Try / catch

try { float v = img.linear_atX(fx, y); } catch (cimg_library::CImgInstanceException& e) { std::cerr << e.what() << '\n'; v = 0; }

Prevention

When it happens

Trigger: Calling linear_atX() on an empty CImg instance (default-constructed, failed load, or zero-sized).

Common situations: Resampling/warping code operating on an image that failed to load; a default-constructed member image; empty result of a crop/extract operation.

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


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/462d5041084b1ca3. Report an issue: GitHub.