Yalantis/uCrop · error · CImgArgumentException

displacement(): Specified guide (%u,%u,%u,%u,%p) has invalid

Error message

displacement(): Specified guide (%u,%u,%u,%u,%p) has invalid dimensions.

What it means

displacement() accepts an optional guide image used to guide the flow estimation. The guide must match the instance image's width, height and depth, and have a spectrum of at least 2 (or 3 for 3D volumes), because it stores flow vector components. If the guide is non-empty but violates these constraints, the library throws this CImgArgumentException.

Source

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

        throw CImgArgumentException(_cimg_instance
                                    "displacement(): Instance and reference image (%u,%u,%u,%u,%p) have "
                                    "different dimensions.",
                                    cimg_instance,
                                    reference._width,reference._height,reference._depth,reference._spectrum,
                                    reference._data);
      if (precision<0)
        throw CImgArgumentException(_cimg_instance
                                    "displacement(): Invalid specified precision %g "
                                    "(should be >=0)",
                                    cimg_instance,
                                    precision);

      const bool is_3d = reference._depth>1;
      const unsigned int spectrum_U = is_3d?3:2;

      if (guide &&
          (guide._width!=_width || guide._height!=_height || guide._depth!=_depth || guide._spectrum<spectrum_U))
        throw CImgArgumentException(_cimg_instance
                                    "displacement(): Specified guide (%u,%u,%u,%u,%p) "
                                    "has invalid dimensions.",
                                    cimg_instance,
                                    guide._width,guide._height,guide._depth,guide._spectrum,guide._data);
      const float
        scale_factor = 2.f,
        abs_smoothness = cimg::abs(smoothness),
        _precision = (float)std::pow(10.,-(double)precision);
      const unsigned int
        min_siz = is_3d?cimg::min(_width,_height,_depth):std::min(_width,_height),
        _nb_scales = nb_scales>0?nb_scales:(unsigned int)cimg::round(std::log(min_siz)/std::log(scale_factor)) - 1;

      float sm, sM = reference.max_min(sm), im, iM = max_min(im);
      const float sdelta = sm==sM?1:(sM - sm), idelta = im==iM?1:(iM - im);

      CImg<floatT> U, C;  // U: vector field, C: constraints field (at current scale)
      for (int scale = (int)_nb_scales - 1; scale>=0; --scale) {
        const float fact = (float)std::pow(scale_factor,(double)scale);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure guide has the same width/height/depth as the instance image
  2. Ensure guide._spectrum >= 2 for 2D (>= 3 for 3D) - typically the guide is a previous flow result with exactly that many channels
  3. Resize/recreate the guide with guide.assign(_width,_height,_depth,spectrum_U) or resize() before calling
  4. Pass a default-constructed empty CImg (CImg<floatT>::const_empty()) if you do not want guidance, since empty guides are skipped

Example fix

// before
CImg<float> guide(img.width(), img.height(), 1, 1); // 1 channel
cimg_forXY(img,i,j) guide(i,j) = prior(i,j);
CImg<float> flow = img.displacement(ref, 0.1f, 5.f, 0, 1000, false, guide);
// after
CImg<float> guide(img.width(), img.height(), 1, 2); // >=2 channels for 2D flow
guide.get_shared_channel(0) = prior_x; guide.get_shared_channel(1) = prior_y;
CImg<float> flow = img.displacement(ref, 0.1f, 5.f, 0, 1000, false, guide);
Defensive patterns

Strategy: validation

Validate before calling

const unsigned int spectrum_U = reference._depth > 1 ? 3 : 2;
if (guide && (guide._width != img._width || guide._height != img._height ||
              guide._depth != img._depth || guide._spectrum < spectrum_U)) {
  guide.resize(img.width(), img.height(), img.depth(), spectrum_U);
}
CImg<float> flow = img.displacement(reference, 0.1f, 5.f, 0, 1000, false, guide);

Type guard

template<typename T>
bool isGuideValid(const CImg<T>& inst, const CImg<T>& guide) {
  const unsigned int minS = inst._depth > 1 ? 3 : 2;
  return !guide || (guide._width == inst._width && guide._height == inst._height &&
                    guide._depth == inst._depth && guide._spectrum >= minS);
}

Try / catch

try {
  CImg<float> flow = img.displacement(reference, 0.1f, 5.f, 0, 1000, false, guide);
} catch (CImgArgumentException& e) {
  std::fprintf(stderr, "invalid guide: %s\n", e.what());
  CImg<float> flow = img.displacement(reference); // run without guidance
}

Prevention

When it happens

Trigger: Calling displacement(reference, ..., guide) with a guide that has different width/height/depth than the instance, a scalar (1-channel) guide, or a 3D case where guide._spectrum < 3.

Common situations: Reusing an output flow field from a previous run on a different-sized image, passing a single-channel image as a guide when vector components are required, or 2D/3D mismatch where the guide was built for the wrong dimensionality.

Related errors


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