Yalantis/uCrop · error · CImgArgumentException

"[" cimg_appname "_math_parser] CImg<%s>: Value accessor '[]

Error message

"[" cimg_appname "_math_parser] CImg<%s>: Value accessor '[]': Out-of-bounds sub-vector request (length: %ld, start: %ld, sub-length: %ld, step: %ld)."

What it means

The math parser value accessor '[]' can extract a sub-vector from a vector value given a start index, sub-length and step. It validates start + step*(sublength-1) against the source vector length; if the requested range extends past the end (or starts before 0), a CImgArgumentException details the length, start, sub-length and step.

Source

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

        }
        return (S2 - S*S/siz)/(siz - 1);
      }

      static double mp_vector_copy(_cimg_math_parser& mp) {
        std::memcpy(&_mp_arg(1) + 1,&_mp_arg(2) + 1,sizeof(double)*mp.opcode[3]);
        return cimg::type<double>::nan();
      }

      static double mp_vector_crop(_cimg_math_parser& mp) {
        double *ptrd = &_mp_arg(1) + 1;
        const double *ptrs = &_mp_arg(2) + 1;
        const longT
          length = (longT)mp.opcode[3],
          start = (longT)_mp_arg(4),
          sublength = (longT)mp.opcode[5],
          step = (longT)_mp_arg(6);
        if (start<0 || start + step*(sublength-1)>=length)
          throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Value accessor '[]': "
                                      "Out-of-bounds sub-vector request "
                                      "(length: %ld, start: %ld, sub-length: %ld, step: %ld).",
                                      mp.imgin.pixel_type(),length,start,sublength,step);
        ptrs+=start;
        if (step==1) std::memcpy(ptrd,ptrs,sublength*sizeof(double));
        else for (longT k = 0; k<sublength; ++k) { *(ptrd++) = *ptrs; ptrs+=step; }
        return cimg::type<double>::nan();
      }

      static double mp_vector_crop_ext(_cimg_math_parser& mp) {
        double *const ptrd = &_mp_arg(1) + 1;
        const double *const ptrs = &_mp_arg(2) + 1;
        const unsigned int
          w = (unsigned int)mp.opcode[3],
          h = (unsigned int)mp.opcode[4],
          d = (unsigned int)mp.opcode[5],
          s = (unsigned int)mp.opcode[6],
          dx = (unsigned int)mp.opcode[11],

View on GitHub (pinned to f788b534b4)

Solutions

  1. Clamp or recompute the slice so that 0 <= start and start + step*(sublength-1) < length.
  2. Reduce sublength or step to fit the available range before slicing.
  3. Compute sublength dynamically from the vector length instead of hard-coding it.
  4. Catch CImgArgumentException and log length/start/sublength/step to locate the bad parameter.

Example fix

// before: V[10,8,2]  // end=24 >= 16
// after:  V[10,3,2]   // end=14 < 16
Defensive patterns

Strategy: validation

Validate before calling

if (start < 0 || start + step * (sublength - 1) >= length)
  throw std::runtime_error("sub-vector slice out of bounds");

Try / catch

try { img.evaluate(sliceExpr); } catch (const CImgArgumentException& e) { log("[] accessor out of bounds: " << e.what()); }

Prevention

When it happens

Trigger: An expression like V[start,sublength,step] where start is negative or start + step*(sublength-1) >= length, e.g. taking 8 elements with step 2 starting at index 10 of a 16-element vector (10 + 2*7 = 24 >= 16).

Common situations: Hard-coded slice parameters reused after the vector's size changed; using step/stride slicing with off-by-one in the last-element computation; dynamic start values from prior computations going out of range.

Related errors


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