Yalantis/uCrop · error · CImgArgumentException

warp(): Instance and specified relative warping field (%u,%u

Error message

warp(): Instance and specified relative warping field (%u,%u,%u,%u,%p) have different XYZ dimensions.

What it means

In relative warping mode (mode != 0), CImg's warp()/get_warp() requires the warping field to have the same width, height, and depth as the image instance being warped (spectra may differ). When is_sameXYZ(p_warp) fails, it throws CImgArgumentException including the warp field's dimensions and data pointer so the mismatch is visible. Relative mode indexes the warp field with the same coordinates as the image, so mismatched XYZ sizes are meaningless.

Source

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

    /**
       \param warp Warping field.
       \param mode Can be { 0=backward-absolute | 1=backward-relative | 2=forward-absolute | 3=foward-relative }
       \param interpolation Can be <tt>{ 0=nearest | 1=linear | 2=cubic }</tt>.
       \param boundary_conditions Boundary conditions <tt>{ 0=dirichlet | 1=neumann | 2=periodic | 3=mirror }</tt>.
    **/
    template<typename t>
    CImg<T>& warp(const CImg<t>& p_warp, const unsigned int mode=0,
                  const unsigned int interpolation=1, const unsigned int boundary_conditions=0) {
      return get_warp(p_warp,mode,interpolation,boundary_conditions).move_to(*this);
    }

    //! Warp image content by a warping field \newinstance.
    template<typename t>
    CImg<T> get_warp(const CImg<t>& p_warp, const unsigned int mode=0,
                     const unsigned int interpolation=1, const unsigned int boundary_conditions=0) const {
      if (is_empty() || !p_warp) return *this;
      if (mode && !is_sameXYZ(p_warp))
        throw CImgArgumentException(_cimg_instance
                                    "warp(): Instance and specified relative warping field (%u,%u,%u,%u,%p) "
                                    "have different XYZ dimensions.",
                                    cimg_instance,
                                    p_warp._width,p_warp._height,p_warp._depth,p_warp._spectrum,p_warp._data);

      CImg<T> res(p_warp._width,p_warp._height,p_warp._depth,_spectrum);

      if (p_warp._spectrum==1) { // 1D warping
        if (mode>=3) { // Forward-relative warp
          res.fill((T)0);
          if (interpolation>=1) // Linear interpolation
            cimg_pragma_openmp(parallel for cimg_openmp_collapse(3) cimg_openmp_if_size(res.size(),4096))
            cimg_forYZC(res,y,z,c) {
              const t *ptrs0 = p_warp.data(0,y,z); const T *ptrs = data(0,y,z,c);
              cimg_forX(res,x) res.set_linear_atX(*(ptrs++),x + (float)*(ptrs0++),y,z,c);
            }
          else // Nearest-neighbor interpolation
            cimg_forYZC(res,y,z,c) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Resize the warping field to match the image XYZ dimensions before warping: p_warp.resize(img.width(), img.height(), img.depth(), p_warp.spectrum(), 3).
  2. Or call warp with mode=0 (absolute) if the field is meant to hold absolute coordinates, which does not require same XYZ sizes.
  3. Ensure the warp field is derived from the same (or identically sized) source image as the one being warped.
  4. Log/compare img.width()/height()/depth() against p_warp dimensions (they appear in the message) to find which pipeline stage changed size.

Example fix

// before
img.warp(field, 1); // field is 320x240, img is 640x480 -> throws
// after
field.resize(img.width(), img.height(), img.depth(), field.spectrum(), 3);
img.warp(field, 1); // XYZ dims now match
Defensive patterns

Strategy: validation

Validate before calling

// C++
if (mode != 0 && !(img.is_sameX(field) && img.is_sameY(field) && img.is_sameZ(field))) {
    field.resize(img.width(), img.height(), img.depth(), field.spectrum(), 3); // linear resize
}
img.warp(field, mode);

Try / catch

try {
    img.warp(field, mode, interp, bc);
} catch (const cimg_library::CImgArgumentException& e) {
    // parse/report dims from e.what(), or auto-align:
    field.resize(img.width(), img.height(), img.depth(), field.spectrum(), 3);
    img.warp(field, mode, interp, bc);
}

Prevention

When it happens

Trigger: Calling img.warp(p_warp, 1 /* relative */) (or get_warp with mode!=0) where p_warp was built at a different resolution than img — e.g. warp field computed from a resized/downscaled image, or created with different width/height/depth. In absolute mode (mode==0) this check is skipped, so switching mode exposes the mismatch.

Common situations: Generating the displacement field at coarse resolution for performance then warping the full-size image; loading a precomputed warp of different dimensions; changing mode from 0 to 1 after upgrading code without resizing the field.

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/0c5c9c7a266fa98b. Report an issue: GitHub.