Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<%s>::%s: %s: Specified input

Error message

[cimg_appname_math_parser] CImg<%s>::%s: %s: Specified input size (%ux%ux%ux%u = %u) does not match size of input variable (%u), in expression '%s'.

What it means

Thrown by the convolution-type opcode in the math parser: the input image variable (opcode[2], a vector) has an element count that disagrees with the computed input extent wI*hI*dI*sI derived from the specified sizes and strides. If a dimension size is unspecified (~0U) it is derived as the image dimension divided by the stride; otherwise it is read from the expression memory. The parser validates the product against size(opcode[2]) before running the operation.

Source

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

                wI = (unsigned int)mem[opcode[3]],
                hI = (unsigned int)mem[opcode[4]],
                dI = (unsigned int)mem[opcode[5]],
                sI = (unsigned int)mem[opcode[6]],
                wK = (unsigned int)mem[opcode[8]],
                hK = (unsigned int)mem[opcode[9]],
                dK = (unsigned int)mem[opcode[10]],
                sK = (unsigned int)mem[opcode[11]],
                channel_mode = (unsigned int)mem[opcode[14]],
                xstride = (int)mem[opcode[18]],
                ystride = (int)mem[opcode[19]],
                zstride = (int)mem[opcode[20]],
                xsize = opcode[27]==~0U?wI/xstride:(unsigned int)mem[opcode[27]],
                ysize = opcode[28]==~0U?hI/ystride:(unsigned int)mem[opcode[28]],
                zsize = opcode[29]==~0U?dI/zstride:(unsigned int)mem[opcode[29]];

              if (wI*hI*dI*sI!=size(opcode[2])) {
                _cimg_mp_strerr;
                throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                            "CImg<%s>::%s: %s: Specified input size (%ux%ux%ux%u = %u) does "
                                            "not match size of input variable (%u), in expression '%s'.",
                                            pixel_type(),_cimg_mp_calling_function,s_op,
                                            wI,hI,dI,sI,wI*hI*dI*sI,size(opcode[2]),
                                            s0);
              }
              if (wK*hK*dK*sK!=size(opcode[7])) {
                _cimg_mp_strerr;
                throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                            "CImg<%s>::%s: %s: Specified kernel size (%ux%ux%ux%u = %u) does "
                                            "not match size of kernel variable (%u), in expression '%s'.",
                                            pixel_type(),_cimg_mp_calling_function,s_op,
                                            wK,hK,dK,sK,wK*hK*dK*sK,size(opcode[7]),
                                            s0);
              }

              arg2 = !channel_mode?sI*sK:channel_mode==1?std::max(sI,sK):
                channel_mode==2?std::max(sI,sK)/std::min(sI,sK):1U;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Make the input vector length exactly wI*hI*dI*sI (verify counts before the call).
  2. Leave the size arguments unspecified (~0U / omit them) so they are derived from the image dimensions and strides instead of hard-coding.
  3. Recompute explicit sizes after any stride change.
  4. Pad or trim the input variable to the declared geometry.

Example fix

// before
convolve(in, k, 16,16,1,3, 1,1) // in has 768 values but 16*16*1*3=768? mismatch -> fix sizes
// after
convolve(in, k, wI,hI,dI,sI, 1,1) // derive sizes, or pass 32,8,1,3 for 768 values
Defensive patterns

Strategy: validation

Validate before calling

size_t inLen = inVec.size();
unsigned long expect = (unsigned long)wI*hI*dI*sI;
if (inLen != expect) throw std::runtime_error("input size " + std::to_string(expect) + " != variable size " + std::to_string(inLen));

Type guard

bool input_fits(const CImg<float>& in, unsigned wI, unsigned hI, unsigned dI, unsigned sI) {
  return (unsigned long)in.size() == (unsigned long)wI*hI*dI*sI;
}

Try / catch

try {
  img.fill(expr.c_str());
} catch (const CImgArgumentException& e) {
  // recompute sizes/strides or pad input before retrying
}

Prevention

When it happens

Trigger: Evaluating an expression-level convolution/pooling where the input variable holds N values but the declared (or stride-derived) input geometry multiplies to M != N; explicitly passing xsize/ysize/zsize arguments inconsistent with the actual input vector; wrong stride values changing the derived defaults.

Common situations: Hand-computing input sizes for a sliding-window op in an expression; changing stride parameters without recomputing sizes; reshaping input data (e.g. after a channel change from RGB to RGBA) without updating the size arguments.

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/09632f2ef9c24285. Report an issue: GitHub.