Yalantis/uCrop · error · CImgArgumentException

get_gradient(): Invalid specified axes

Error message

get_gradient(): Invalid specified axes '%s'.

What it means

CImg's get_gradient() computes image gradients along the axes given as a string. Each character of the axes string must be 'x', 'y' or 'z'; the library validates the string character-by-character and throws this CImgArgumentException if any character is not one of the three allowed axis letters.

Solutions

  1. Inspect the axes string at the throw site and remove/replace any character that is not 'x','y' or 'z' (case-insensitive)
  2. Use only concatenated axis letters with no separators, e.g. 'xy' or 'xyz'
  3. Lowercase/normalize user-supplied axis names before passing them, or build the string programmatically from a whitelist
  4. If you need derivatives along other dimensions (spectrum/time), compute them with get_derivative() along that dimension instead

Example fix

// before
img.get_gradient("x,t");
// after
img.get_gradient("x"); // or "xy" / "xyz" - only x,y,z are valid
Defensive patterns

Strategy: validation

Validate before calling

static bool isValidAxes(const std::string& axes) {
  for (char c : axes) {
    char l = (char)std::tolower((unsigned char)c);
    if (l != 'x' && l != 'y' && l != 'z') return false;
  }
  return !axes.empty();
}
// call only if isValidAxes(axes)
CImg<float> grad = img.get_gradient(axes.c_str());

Type guard

bool isCimgAxis(char c) {
  char l = (char)std::tolower((unsigned char)c);
  return l == 'x' || l == 'y' || l == 'z';
}

Try / catch

try {
  CImg<float> grad = img.get_gradient(axes);
} catch (CImgArgumentException& e) {
  std::fprintf(stderr, "bad axes string '%s': %s\n", axes.c_str(), e.what());
  // fall back to default full gradient
  CImg<float> grad = img.get_gradient("xy");
}

Prevention

When it happens

Trigger: Calling get_gradient(axes) (or gradient() which delegates to it) with an axes string containing any character other than 'x','y','z' (or 'X','Y','Z', which are lowercased) - e.g. 'w', 't', 'xy z', or a string with trailing whitespace/punctuation.

Common situations: Typo in the axes string ('X,Y' with commas), porting code that used axis indices or different axis names, accidentally passing a user/config string with spaces, or handling 4D images where a developer passes 't' for the time axis which get_gradient does not support.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

       - 4 = Using Deriche recursive filter.
       - 5 = Using Van Vliet recursive filter.
    **/
    CImgList<Tfloat> get_gradient(const char *const axes=0, const int scheme=0) const {
      CImgList<Tfloat> res;
      char __axes[4] = {};
      const char *_axes = axes?axes:__axes;
      if (!axes) {
        unsigned int k = 0;
        if (_width>1) __axes[k++] = 'x';
        if (_height>1) __axes[k++] = 'y';
        if (_depth>1) __axes[k++] = 'z';
      }

      CImg<Tfloat> grad;
      while (*_axes) {
        const char axis = cimg::lowercase(*(_axes++));
        if (axis!='x' && axis!='y' && axis!='z')
          throw CImgArgumentException(_cimg_instance
                                      "get_gradient(): Invalid specified axes '%s'.",
                                      cimg_instance,
                                      axes);
        const longT off = axis=='x'?1:axis=='y'?_width:_width*_height;
        if ((axis=='x' && _width==1) || (axis=='y' && _height==1) || (axis=='z' && _depth==1)) {
          grad.assign(_width,_height,_depth,_spectrum,0).move_to(res);
          continue;
        }

        const int _scheme = axis=='z' && (scheme==2 || scheme==3)?0:scheme;
        switch (_scheme) {
        case -1 : { // Backward finite differences
          grad.assign(_width,_height,_depth,_spectrum);
          cimg_pragma_openmp(parallel for cimg_openmp_collapse(3) cimg_openmp_if_size(size(),16384))
          cimg_forXYZC(*this,x,y,z,c) {
            const ulongT pos = offset(x,y,z,c);
            if ((axis=='x' && !x) || (axis=='y' && !y) || (axis=='z' && !z))
              grad[pos] = 0;

View on GitHub (pinned to f788b534b4)