Yalantis/uCrop · warning

data(): Invalid pointer request, at coordinates (%u,%u,%u,%u

Error message

data(): Invalid pointer request, at coordinates (%u,%u,%u,%u) [offset=%u].

What it means

CImg<T>::data(x,y,z,c) returns the raw pointer to the pixel at the given coordinates; in debug builds (cimg_verbosity>=3) it warns non-fatally when the computed offset is >= size(), i.e. the coordinates lie outside the image. Unlike operator(), it still returns the out-of-range pointer (_data+off), so the caller would silently read/write out-of-bounds memory unless the warning is heeded.

Source

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

    //! Return a pointer to a located pixel value.
    /**
       Return a \c T*, or a \c const \c T* pointer to the value located at (\c x,\c y,\c z,\c c) in the pixel buffer
       of the image instance,
       whether the instance is \c const or not.
       \param x X-coordinate of the pixel value.
       \param y Y-coordinate of the pixel value.
       \param z Z-coordinate of the pixel value.
       \param c C-coordinate of the pixel value.
       \note
       - Writing \c img.data(x,y,z,c) is equivalent to <tt>&(img(x,y,z,c))</tt>. Thus, this method has the same
         properties as operator()(unsigned int,unsigned int,unsigned int,unsigned int).
     **/
#if cimg_verbosity>=3
    T *data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) {
      const ulongT off = (ulongT)offset(x,y,z,c);
      if (off>=size())
        cimg::warn(_cimg_instance
                   "data(): Invalid pointer request, at coordinates (%u,%u,%u,%u) [offset=%u].",
                   cimg_instance,
                   x,y,z,c,off);
      return _data + off;
    }

    //! Return a pointer to a located pixel value \const.
    const T* data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) const {
      return const_cast<CImg<T>*>(this)->data(x,y,z,c);
    }
#else
    T* data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) {
      return _data + x + (ulongT)y*_width + (ulongT)z*_width*_height + (ulongT)c*_width*_height*_depth;
    }

    const T* data(const unsigned int x, const unsigned int y=0, const unsigned int z=0, const unsigned int c=0) const {
      return _data + x + (ulongT)y*_width + (ulongT)z*_width*_height + (ulongT)c*_width*_height*_depth;
    }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Validate x<img.width(), y<img.height(), z<img.depth(), c<img.spectrum() before calling data(x,y,z,c)
  2. Use data() with no arguments to get the buffer start and index manually with checked offsets
  3. Prefer operator()/at() accessors over raw pointers unless performance requires otherwise
  4. Assert image non-emptiness and dimensions in debug builds before pointer arithmetic

Example fix

// before
T* p = img.data(x, y); // x,y may exceed bounds
// after
if (x < img.width() && y < img.height()) { T* p = img.data(x, y); ... }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(x < img.width() && y < img.height() && z < img.depth() && c < img.spectrum()))
  throw std::out_of_range("data() request out of bounds");

Type guard

template <typename T>
T* safe_data(CImg<T>& img, unsigned x, unsigned y, unsigned z = 0, unsigned c = 0) {
  if (x < img.width() && y < img.height() && z < img.depth() && c < img.spectrum())
    return img.data(x, y, z, c);
  return nullptr;
}

Prevention

When it happens

Trigger: Calling img.data(x,y,z,c) with coordinates beyond [width,height,depth,spectrum], or on an image whose allocation failed/zero-size while passing nonzero coordinates.

Common situations: Pointer-based pixel manipulation loops with wrong strides, passing pixel coordinates instead of channel-relative offsets, calling data() on a default-constructed CImg with nonzero coords.

Related errors


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