Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<%s>::%s: %s: Input vector si

Error message

[cimg_appname_math_parser] CImg<%s>::%s: %s: Input vector size (%lu values) and its specified geometry (%u,%u,%u,%u) (%lu values) do not match.

What it means

Thrown when a math-parser opcode fills or reshapes a named vector variable whose actual stored size does not match the geometry (w,h,z,c product) supplied to the call. The parser multiplies the four geometry components and compares to the vector's element count p1; a mismatch means the declared shape cannot index the existing buffer. This protects against out-of-bounds access when a vector is reinterpreted with a different shape.

Source

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

                                              opcode._height<5?"few":"much",s0);
                }

                _cimg_mp_check_const_scalar((unsigned int)opcode[1],2,3); // w
                opcode[1] = (ulongT)mem[opcode[1]];
                _cimg_mp_check_const_scalar((unsigned int)opcode[2],3,3); // h
                opcode[2] = (ulongT)mem[opcode[2]];
                _cimg_mp_check_const_scalar((unsigned int)opcode[3],4,3); // d
                opcode[3] = (ulongT)mem[opcode[3]];
                _cimg_mp_check_const_scalar((unsigned int)opcode[4],5,3); // s
                opcode[4] = (ulongT)mem[opcode[4]];
                p1 = size((unsigned int)opcode[0]);
                arg2 = (unsigned int)opcode[1];
                arg3 = (unsigned int)opcode[2];
                arg4 = (unsigned int)opcode[3];
                arg5 = (unsigned int)opcode[4];
                if (arg2*arg3*arg4*arg5!=p1) {
                  _cimg_mp_strerr;
                  throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                              "CImg<%s>::%s: %s: Input vector size (%lu values) and its specified "
                                              "geometry (%u,%u,%u,%u) (%lu values) do not match.",
                                              pixel_type(),_cimg_mp_calling_function,s_op,
                                              p1,arg2,arg3,arg4,arg5,(ulongT)arg2*arg3*arg4*arg5);
                }
                if (opcode[9]!=(ulongT)~0U) {
                  _cimg_mp_check_const_scalar((unsigned int)opcode[9],arg1,3);
                  opcode[9] = (ulongT)mem[opcode[9]];
                } else opcode[9] = opcode[1];
                if (opcode[10]!=(ulongT)~0U) {
                  _cimg_mp_check_const_scalar((unsigned int)opcode[10],arg1 + 1,3);
                  opcode[10] = (ulongT)mem[opcode[10]];
                } else opcode[10] = opcode[2];
                if (opcode[11]!=(ulongT)~0U) {
                  _cimg_mp_check_const_scalar((unsigned int)opcode[11],arg1 + 2,3);
                  opcode[11] = (ulongT)mem[opcode[11]];
                } else opcode[11] = opcode[3];
                if (opcode[12]!=(ulongT)~0U) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Make w*h*z*c exactly equal the vector's element count (e.g. 5 values need geometry like 5,1,1,1).
  2. Use `[...]`-free auto geometry (omit the explicit size argument) and let the parser infer the shape.
  3. Print the vector length inside the expression (e.g. via a debug fill) and adjust the declared geometry to match.
  4. Compute geometry programmatically from the data instead of hard-coding it.

Example fix

// before
v = [1,2,3,4,5]; reshape(v,2,3,1,1); // 2*3=6 != 5
// after
v = [1,2,3,4,5]; reshape(v,5,1,1,1);
Defensive patterns

Strategy: validation

Validate before calling

size_t n = vec.size();
unsigned long declared = (unsigned long)w*h*z*c;
if (declared != n) throw std::runtime_error("geometry " + std::to_string(declared) + " != vector size " + std::to_string(n));

Type guard

bool geometry_matches(const CImg<float>& vec, unsigned w, unsigned h, unsigned z, unsigned c) {
  return (unsigned long)vec.size() == (unsigned long)w*h*z*c;
}

Try / catch

try {
  img.fill(expr.c_str());
} catch (const CImgArgumentException& e) {
  // geometry mismatch: fall back to inferred geometry
}

Prevention

When it happens

Trigger: Evaluating an expression that assigns/reshapes a vector with an explicit 4D geometry, e.g. something like `V = [w,h,z,c]` / `assign(geometry,...)` style opcodes, where the vector literal or variable holds N values but w*h*z*c != N (e.g. declaring geometry 2x3 for a 5-element vector).

Common situations: Declaring a vector with `[a,b,c]` then passing an inconsistent geometry string to a command; refactoring an expression to change vector contents without updating the declared size; off-by-one in computed geometry inside the expression.

Understand the failure class

Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.

Related errors


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