Yalantis/uCrop · error · CImgArgumentException

[" cimg_appname "_math_parser] CImg<%s>::%s: %s%s Specified

Error message

[" cimg_appname "_math_parser] CImg<%s>::%s: %s%s Specified image index is not a constant, in expression '%s'.

What it means

check_const_index() validates that an image-index argument inside a math expression is a compile-time constant scalar. Multi-image expressions in CImg reference images by index (e.g. I0, I[#1,...] style access or functions taking an image number), and these indices must be resolvable at compile time. If the index expression is not a constant scalar, the parser throws CImgArgumentException.

Source

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

          char *s0;
          _cimg_mp_strerr;
          throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                      "CImg<%s>::%s: %s%s %s%s (of type '%s' and value %g) is not a%s constant, "
                                      "in expression '%s'.",
                                      pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"",
                                      s_arg,*s_arg?" argument":" Argument",s_type(arg)._data,val,
                                      !mode?"":mode==1?"n integer":
                                      mode==2?" positive integer":" strictly positive integer",s0);
        }
      }

      // Check if an image index is a constant value.
      void check_const_index(const unsigned int arg,
                             char *const ss, char *const se, const char saved_char) {
        if (arg!=~0U && !is_const_scalar(arg)) {
          char *s0;
          _cimg_mp_strerr;
          throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                      "CImg<%s>::%s: %s%s Specified image index is not a constant, "
                                      "in expression '%s'.",
                                      pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"",s0);
        }
      }

      // Check that specified constant is not nan.
      void check_notnan_index(const unsigned int arg, const char *const s_arg,
                              char *const ss, char *const se, const char saved_char) {
        if (arg!=~0U &&
            (arg==_cimg_mp_slot_nan || (is_const_scalar(arg) && cimg::type<double>::is_nan(mem[arg])))) {
          char *s0;
          _cimg_mp_strerr;
          throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                      "CImg<%s>::%s: %s%s Specified index '%s' is NaN.",
                                      pixel_type(),_cimg_mp_calling_function,s_op,*s_op?":":"",s_arg);
        }
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Replace the dynamic image index with a literal integer index
  2. If you need to process several images, loop in C++ and call the expression per image index, injecting the literal index via snprintf
  3. Restructure the expression so the image selection happens outside the expression (e.g. select the image with img.select() before evaluation)
  4. Use compile-time constant subexpressions (numeric literals, const variables) for the index argument

Example fix

// before
img.fill("I[#(z)]"); // dynamic image index not allowed
// after
for (int k = 0; k < nb_images; ++k) {
  char expr[64];
  snprintf(expr, sizeof(expr), "I[#%d]", k);
  images[k].fill(expr); // literal constant index
}
Defensive patterns

Strategy: validation

Validate before calling

// C++: only allow literal indices; reject anything else before the CImg call
std::string make_indexed_expr(int image_index) {
  if (image_index < 0) throw std::invalid_argument("image index must be a constant >= 0");
  char buf[64];
  std::snprintf(buf, sizeof(buf), "I[#%d]", image_index);
  return std::string(buf);
}

Type guard

bool is_literal_index(const std::string& idx_expr) {
  return !idx_expr.empty() &&
         idx_expr.find_first_not_of("0123456789") == std::string::npos;
}

Try / catch

try {
  img.fill(expr.c_str());
} catch (const cimg_library::CImgArgumentException& e) {
  std::cerr << "Image index must be constant: " << e.what() << std::endl;
}

Prevention

When it happens

Trigger: Using a computed or runtime expression as an image index, e.g. I[#(z+1),...] or passing a variable/pixel-derived value where a literal image number like 0 or 1 is required; arg==~0U (no index) is allowed, but any non-constant index argument is rejected.

Common situations: Trying to iterate over image indices inside the expression language (loops over image numbers); using per-pixel values to select an image dynamically; porting scripts where dynamic image selection seemed supported but is not at parse time.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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