Yalantis/uCrop · error · CImgArgumentException

draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%

Error message

draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.

What it means

This z-buffered draw_triangle() overload draws into a Z-buffer that must have exactly the same width, height, depth and spectrum as the image instance. is_sameXY(zbuffer) fails when dimensions differ, so the library throws CImgArgumentException reporting the z-buffer's actual (w,h,d,s,ptr). Mixing images of different sizes (or a z-buffer from another image) triggers it.

Source

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

       \param z2 Z-coordinate of the third vertex.
       \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color.
       \param opacity Drawing opacity.
       \param brightness Brightness factor.
    **/
    template<typename tz, typename tc>
    CImg<T>& draw_triangle(CImg<tz>& zbuffer,
                           int x0, int y0, const float z0,
                           int x1, int y1, const float z1,
                           int x2, int y2, const float z2,
                           const tc *const color, const float opacity=1,
                           const float brightness=1) {
      if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this;
      if (!color)
        throw CImgArgumentException(_cimg_instance
                                    "draw_triangle(): Specified color is (null).",
                                    cimg_instance);
      if (!is_sameXY(zbuffer))
        throw CImgArgumentException(_cimg_instance
                                    "draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have "
                                    "different dimensions.",
                                    cimg_instance,
                                    zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);

      float iz0 = 1/z0, iz1 = 1/z1, iz2 = 1/z2;
      if (y0>y1) cimg::swap(x0,x1,y0,y1,iz0,iz1);
      if (y0>y2) cimg::swap(x0,x2,y0,y2,iz0,iz2);
      if (y1>y2) cimg::swap(x1,x2,y1,y2,iz1,iz2);
      if (y2<0 || y0>=height() || cimg::min(x0,x1,x2)>=width() || cimg::max(x0,x1,x2)<0 || !opacity) return *this;

      const int w1 = width() - 1, h1 = height() - 1, cy0 = cimg::cut(y0,0,h1), cy2 = cimg::cut(y2,0,h1);
      const longT
        dx01 = (longT)x1 - x0, dx02 = (longT)x2 - x0, dx12 = (longT)x2 - x1,
        dy01 = std::max((longT)1,(longT)y1 - y0),
        dy02 = std::max((longT)1,(longT)y2 - y0),
        dy12 = std::max((longT)1,(longT)y2 - y1),
        hdy01 = dy01/2, hdy02 = dy02/2, hdy12 = dy12/2;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Re-create the z-buffer to match: CImg<float> zbuffer(img.width(),img.height(),1,1,0) before drawing
  2. If the image was resized, reallocate the z-buffer with the new dimensions
  3. Ensure you pass the z-buffer belonging to the same render target, not another image's
  4. Check both dims with img.is_sameXY(zbuffer) before the call

Example fix

// before
CImg<float> zbuffer(640,480,1,1,0);
img.resize(1280,720);
img.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,col,opacity); // dimension mismatch
// after
img.resize(1280,720);
CImg<float> zbuffer(img.width(),img.height(),1,1,0); // matches instance
img.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,col,opacity);
Defensive patterns

Strategy: validation

Validate before calling

if (!zbuffer.is_empty() && img.is_sameXY(zbuffer)) { img.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,color,opacity); }

Type guard

template<typename T> bool zbufferMatches(const CImg<T>& zb, const CImg<U>& img) { return img.is_sameXY(zb); }

Try / catch

try { img.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,color,opacity); } catch (const CImgArgumentException& e) { zbuffer.assign(img.width(),img.height(),1,1,0); /* retry */ }

Prevention

When it happens

Trigger: Calling draw_triangle(...,zbuffer,...) where zbuffer was allocated for a different-sized image; reusing a z-buffer after resizing the target image; passing an empty (default-constructed) CImg as zbuffer.

Common situations: Resizing the render target without re-allocating the z-buffer; copying z-buffer code between images of different resolution; passing an uninitialized CImg<float> zbuf; off-by-one dimensions when creating the z-buffer.

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/20d303dd6cf1e214. Report an issue: GitHub.