{"record":{"id":"20d303dd6cf1e214","repo":"Yalantis/uCrop","slug":"draw-triangle-instance-and-specified-z-buffer","errorCode":null,"errorMessage":"draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.","messagePattern":"draw_triangle\\(\\): Instance and specified Z-buffer \\(%u,%u,%u,%u,%p\\) have different dimensions\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":50758,"sourceCode":"       \\param z2 Z-coordinate of the third vertex.\n       \\param color Pointer to \\c spectrum() consecutive values of type \\c T, defining the drawing color.\n       \\param opacity Drawing opacity.\n       \\param brightness Brightness factor.\n    **/\n    template<typename tz, typename tc>\n    CImg<T>& draw_triangle(CImg<tz>& zbuffer,\n                           int x0, int y0, const float z0,\n                           int x1, int y1, const float z1,\n                           int x2, int y2, const float z2,\n                           const tc *const color, const float opacity=1,\n                           const float brightness=1) {\n      if (is_empty() || z0<=0 || z1<=0 || z2<=0) return *this;\n      if (!color)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_triangle(): Specified color is (null).\",\n                                    cimg_instance);\n      if (!is_sameXY(zbuffer))\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_triangle(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have \"\n                                    \"different dimensions.\",\n                                    cimg_instance,\n                                    zbuffer._width,zbuffer._height,zbuffer._depth,zbuffer._spectrum,zbuffer._data);\n\n      float iz0 = 1/z0, iz1 = 1/z1, iz2 = 1/z2;\n      if (y0>y1) cimg::swap(x0,x1,y0,y1,iz0,iz1);\n      if (y0>y2) cimg::swap(x0,x2,y0,y2,iz0,iz2);\n      if (y1>y2) cimg::swap(x1,x2,y1,y2,iz1,iz2);\n      if (y2<0 || y0>=height() || cimg::min(x0,x1,x2)>=width() || cimg::max(x0,x1,x2)<0 || !opacity) return *this;\n\n      const int w1 = width() - 1, h1 = height() - 1, cy0 = cimg::cut(y0,0,h1), cy2 = cimg::cut(y2,0,h1);\n      const longT\n        dx01 = (longT)x1 - x0, dx02 = (longT)x2 - x0, dx12 = (longT)x2 - x1,\n        dy01 = std::max((longT)1,(longT)y1 - y0),\n        dy02 = std::max((longT)1,(longT)y2 - y0),\n        dy12 = std::max((longT)1,(longT)y2 - y1),\n        hdy01 = dy01/2, hdy02 = dy02/2, hdy12 = dy12/2;","sourceCodeStart":50740,"sourceCodeEnd":50776,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L50740-L50776","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-create the z-buffer to match: CImg<float> zbuffer(img.width(),img.height(),1,1,0) before drawing","If the image was resized, reallocate the z-buffer with the new dimensions","Ensure you pass the z-buffer belonging to the same render target, not another image's","Check both dims with img.is_sameXY(zbuffer) before the call"],"exampleFix":"// before\nCImg<float> zbuffer(640,480,1,1,0);\nimg.resize(1280,720);\nimg.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,col,opacity); // dimension mismatch\n// after\nimg.resize(1280,720);\nCImg<float> zbuffer(img.width(),img.height(),1,1,0); // matches instance\nimg.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,col,opacity);","handlingStrategy":"validation","validationCode":"if (!zbuffer.is_empty() && img.is_sameXY(zbuffer)) { img.draw_triangle(x0,y0,z0,x1,y1,z1,x2,y2,z2,zbuffer,color,opacity); }","typeGuard":"template<typename T> bool zbufferMatches(const CImg<T>& zb, const CImg<U>& img) { return img.is_sameXY(zb); }","tryCatchPattern":"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 */ }","preventionTips":["Allocate the z-buffer from the image's own dimensions: CImg<float>(img.width(),img.height(),1,1,0)","Re-create z-buffers after any resize of the render target","Keep z-buffer and image lifetime tied (e.g. a RenderTarget struct)","Assert is_sameXY in debug builds before drawing"],"tags":["cimg","dimension-mismatch","zbuffer","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}