Yalantis/uCrop · error · CImgInstanceException

linear_atXY_p(): Empty instance.

Error message

linear_atXY_p(): Empty instance.

What it means

CImg<T>::linear_atXY_p(fx,fy,z,c) returns a bilinearly interpolated value with periodic (wrap-around) boundary conditions on both X and Y coordinates. It throws CImgInstanceException when the instance is empty since interpolation needs an allocated pixel buffer.

Source

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

      const unsigned int
        x = (unsigned int)nfx,
        y = (unsigned int)nfy;
      const float
        dx = nfx - x,
        dy = nfy - y;
      const unsigned int
        nx = dx>0?x + 1:x,
        ny = dy>0?y + 1:y;
      const Tfloat
        Icc = (Tfloat)(*this)(x,y,z,c),  Inc = (Tfloat)(*this)(nx,y,z,c),
        Icn = (Tfloat)(*this)(x,ny,z,c), Inn = (Tfloat)(*this)(nx,ny,z,c);
      return Icc + (Inc - Icc + (Icc + Inn - Icn - Inc)*dy)*dx + (Icn - Icc)*dy;
    }

    //! Return pixel value, using linear interpolation and periodic boundary conditions for the X and Y-coordinates.
    Tfloat linear_atXY_p(const float fx, const float fy, const int z=0, const int c=0) const {
      if (is_empty())
        throw CImgInstanceException(_cimg_instance
                                    "linear_atXY_p(): Empty instance.",
                                    cimg_instance);

      return _linear_atXY_p(fx,fy,z,c);
    }

    Tfloat _linear_atXY_p(const float fx, const float fy, const int z=0, const int c=0) const {
      const float
        nfx = cimg::mod(fx,_width - 0.5f),
        nfy = cimg::mod(fy,_height - 0.5f);
      const unsigned int
        x = (unsigned int)nfx,
        y = (unsigned int)nfy;
      const float
        dx = nfx - x,
        dy = nfy - y;
      const unsigned int
        nx = cimg::mod(x + 1,_width),

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check img.is_empty() before invoking linear_atXY_p.
  2. Ensure the image data was loaded or allocated before sampling.
  3. Fix upstream producers so they never emit empty images (validate after load).
  4. Prefer _linear_atXY_p() only when non-emptiness is already enforced.

Example fix

// before
float v = img.linear_atXY_p(fx, fy);
// after
if (!img.is_empty()) {
  float v = img.linear_atXY_p(fx, fy);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!img.is_empty()) { float v = img.linear_atXY_p(fx, fy); } else { /* load or fail */ }

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling linear_atXY_p() on an empty CImg (never assigned, failed load, zero dimensions).

Common situations: Seamless/tiling image operations on an image that failed to load; texture sampling in panorama stitching with an empty source frame.

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/8f3734d6bfc94a49. Report an issue: GitHub.