Yalantis/uCrop · error · CImgArgumentException

"[" cimg_appname "_math_parser] CImg<%s>: Function 'copy()':

Error message

"[" cimg_appname "_math_parser] CImg<%s>: Function 'copy()': Out-of-bounds image pointer (length: %ld, increment: %ld, offset start: %ld, offset end: %ld, offset max: %lu)."

What it means

The math parser 'copy()' variant that writes into an image validates that the computed start offset and end offset (start + (siz-1)*inc) are inside the target image (0 <= off < img.size()). If the destination range falls outside the image buffer, a CImgArgumentException with the pointer details is thrown to prevent buffer overrun.

Source

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

        longT off = 0;
        if (is_relative) {
          ox = (int)mp.mem[_cimg_mp_slot_x];
          oy = (int)mp.mem[_cimg_mp_slot_y];
          oz = (int)mp.mem[_cimg_mp_slot_z];
          oc = (int)mp.mem[_cimg_mp_slot_c];
          off = img.offset(ox,oy,oz,oc);
        }
        if ((*p_ref)%2) {
          const int
            x = (int)mp.mem[p_ref[3]],
            y = (int)mp.mem[p_ref[4]],
            z = (int)mp.mem[p_ref[5]],
            c = *p_ref==5?0:(int)mp.mem[p_ref[6]];
          off+=img.offset(x,y,z,c);
        } else off+=(longT)mp.mem[p_ref[3]];
        const longT eoff = off + (siz - 1)*inc;
        if (off<0 || eoff>=(longT)img.size())
          throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Function 'copy()': "
                                      "Out-of-bounds image pointer "
                                      "(length: %ld, increment: %ld, offset start: %ld, "
                                      "offset end: %ld, offset max: %lu).",
                                      mp.imgin.pixel_type(),siz,inc,off,eoff,img.size() - 1);
        return (float*)&img[off];
      }

      static double mp_memcopy(_cimg_math_parser& mp) {
        longT siz = (longT)_mp_arg(4);
        const longT inc_d = (longT)_mp_arg(5), inc_s = (longT)_mp_arg(6);
        const float
          _opacity = (float)_mp_arg(7),
          opacity = (float)cimg::abs(_opacity),
          omopacity = 1 - std::max(_opacity,0.f);
        if (siz>0) {
          const bool
            is_doubled = mp.opcode[8]<=1,
            is_doubles = mp.opcode[15]<=1;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Verify img.size() (w*h*d*s) is large enough for the destination range before running the expression.
  2. Reduce the copy length or increment so off + (siz-1)*inc < img.size().
  3. Fix the x,y,z,c source coordinates so img.offset(x,y,z,c) lands inside the image.
  4. Catch CImgArgumentException and report the computed off/eoff to the user.

Example fix

// before: copy(#0, w*h, 4, 4, patch)  // past image end
// after:  copy(#0, 0, 4, 4, patch)
Defensive patterns

Strategy: validation

Validate before calling

const longT n = (longT)img.size();
if (off < 0 || off + (siz - 1) * inc >= n)
  throw std::runtime_error("copy() would overflow the target image");

Try / catch

try { img.evaluate(expr); } catch (const CImgArgumentException& e) { log("image copy out of bounds: " << e.what()); }

Prevention

When it happens

Trigger: copy(#ind,...) writing N values with stride inc into an image, where the computed end offset is >= img.size(), e.g. copy(#0, x + w*h, siz, inc, ...) near the image end, or x,y,z,c coordinates whose linear offset exceeds the image extent.

Common situations: Blitting a patch with a size larger than the destination image; coordinate arithmetic mistakes (width vs width-1); operating on an image after it was cropped/resized smaller.

Related errors


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