{"record":{"id":"c08469ad7de4644f","repo":"Yalantis/uCrop","slug":"draw-line-instance-and-specified-z-buffer-u","errorCode":null,"errorMessage":"draw_line(): Instance and specified Z-buffer (%u,%u,%u,%u,%p) have different dimensions.","messagePattern":"draw_line\\(\\): 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":49981,"sourceCode":"       \\param z1 Z-coordinate of the ending point.\n       \\param color Pointer to \\c spectrum() consecutive values of type \\c T, defining the drawing color.\n       \\param opacity Drawing opacity.\n       \\param pattern An integer whose bits describe the line pattern.\n       \\param init_hatch Tells if a reinitialization of the hash state must be done.\n    **/\n    template<typename tz, typename tc>\n    CImg<T>& draw_line(CImg<tz>& zbuffer,\n                       int x0, int y0, const float z0,\n                       int x1, int y1, const float z1,\n                       const tc *const color, const float opacity=1,\n                       const unsigned int pattern=~0U, const bool init_hatch=true) {\n      if (is_empty() || z0<=0 || z1<=0 || !opacity || !pattern) return *this;\n      if (!color)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_line(): Specified color is (null).\",\n                                    cimg_instance);\n      if (!is_sameXY(zbuffer))\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_line(): 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      if (std::min(y0,y1)>=height() || std::max(y0,y1)<0 || std::min(x0,x1)>=width() || std::max(x0,x1)<0)\n        return *this;\n      int\n        w1 = width() - 1, h1 = height() - 1,\n        dx01 = x1 - x0, dy01 = y1 - y0;\n      float iz0 = 1/z0, iz1 = 1/z1, diz01 = iz1 - iz0;\n\n      const bool is_horizontal = cimg::abs(dx01)>cimg::abs(dy01);\n      if (is_horizontal) cimg::swap(x0,y0,x1,y1,w1,h1,dx01,dy01);\n      if (pattern==~0U && y0>y1) {\n        cimg::swap(x0,x1,y0,y1,iz0,iz1);\n        dx01*=-1; dy01*=-1; diz01*=-1;\n      }","sourceCodeStart":49963,"sourceCodeEnd":49999,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L49963-L49999","documentation":"When drawing a 3D line with depth testing, the caller must supply a Z-buffer image with exactly the same width and height as the target image (checked via is_sameXY). If the zbuffer argument has different dimensions (or is empty), the library throws this CImgArgumentException because depth writes would be out of bounds.","triggerScenarios":"Calling img.draw_line(x0,y0,z0,x1,y1,z1,color,zbuffer) where zbuffer was allocated with a different size than img, or is a default-constructed/empty CImg, or was resized after img was resized (e.g. image loaded/assign() later while zbuffer kept old dimensions).","commonSituations":"Resizing the target image (resize/assign/load) without also resizing the Z-buffer; reusing one zbuffer across images of different sizes; forgetting to initialize the zbuffer before the first draw call; mixing images from different loads in a render loop.","solutions":["Allocate the Z-buffer with the same dimensions as the target: CImg<float> zbuffer(img.width(),img.height(),1,1,0).","Re-resize the zbuffer whenever the target image changes size: zbuffer.assign(img.width(),img.height(),1,1,0); zbuffer.fill(0);","Guard the call: if (zbuffer && img.is_sameXY(zbuffer)) img.draw_line(...,zbuffer);","If no depth testing is needed, call the 2D draw_line overload that does not take a zbuffer."],"exampleFix":"// before\nCImg<float> zbuffer; // empty\nimg.draw_line(0,0,1,50,50,1,color,zbuffer); // throws\n\n// after\nCImg<float> zbuffer(img.width(),img.height(),1,1,0);\nzbuffer.fill(0);\nimg.draw_line(0,0,1,50,50,1,color,zbuffer);","handlingStrategy":"validation","validationCode":"if (zbuffer && img.is_sameXY(zbuffer)) {\n  img.draw_line(x0,y0,z0,x1,y1,z1,color,zbuffer);\n} else {\n  zbuffer.assign(img.width(),img.height(),1,1,0);\n}","typeGuard":"bool usable_zbuffer(const CImg<float>& zb, const CImg<unsigned char>& img) {\n  return !zb.is_empty() && img.is_sameXY(zb);\n}","tryCatchPattern":"try {\n  img.draw_line(x0,y0,z0,x1,y1,z1,color,zbuffer);\n} catch (CImgArgumentException& e) {\n  zbuffer.assign(img.width(),img.height(),1,1,0);\n  std::fprintf(stderr, \"zbuffer resized: %s\\n\", e.what());\n}","preventionTips":["Initialize the zbuffer together with the image: CImg<float> zb(img.width(),img.height(),1,1,0).","Re-assign the zbuffer every time the target image is resized or reloaded.","Assert is_sameXY(zbuffer) in debug builds before rendering.","Keep the zbuffer and image in the same struct/scope so they stay in sync."],"tags":["cimg","zbuffer","dimension-mismatch","graphics"],"backgroundTag":"shape-mismatch","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"}