{"record":{"id":"e13d157d91a8f71e","repo":"Yalantis/uCrop","slug":"draw-triangle-invalid-specified-texture-u-u","errorCode":null,"errorMessage":"draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).","messagePattern":"draw_triangle\\(\\): Invalid specified texture \\(%u,%u,%u,%u,%p\\)\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":51079,"sourceCode":"       \\param ty1 Y-coordinate of the second vertex in the texture image.\n       \\param tx2 X-coordinate of the third vertex in the texture image.\n       \\param ty2 Y-coordinate of the third vertex in the texture image.\n       \\param opacity Drawing opacity.\n       \\param brightness Brightness factor of the drawing (in [0,2]).\n    **/\n    template<typename tc>\n    CImg<T>& draw_triangle(int x0, int y0,\n                           int x1, int y1,\n                           int x2, int y2,\n                           const CImg<tc>& texture,\n                           int tx0, int ty0,\n                           int tx1, int ty1,\n                           int tx2, int ty2,\n                           const float opacity=1,\n                           const float brightness=1) {\n      if (is_empty()) return *this;\n      if (texture._depth>1 || texture._spectrum<_spectrum)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_triangle(): Invalid specified texture (%u,%u,%u,%u,%p).\",\n                                    cimg_instance,\n                                    texture._width,texture._height,texture._depth,texture._spectrum,texture._data);\n      if (is_overlapped(texture))\n        return draw_triangle(x0,y0,x1,y1,x2,y2,+texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness);\n\n      if (y0>y1) cimg::swap(x0,x1,y0,y1,tx0,tx1,ty0,ty1);\n      if (y0>y2) cimg::swap(x0,x2,y0,y2,tx0,tx2,ty0,ty2);\n      if (y1>y2) cimg::swap(x1,x2,y1,y2,tx1,tx2,ty1,ty2);\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":51061,"sourceCodeEnd":51097,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L51061-L51097","documentation":"This texture-mapped draw_triangle() overload requires the texture to be a 2D image whose spectrum (channels) is at least as large as the instance's _spectrum. When texture._depth>1 (a volumetric texture) or texture._spectrum<_spectrum (too few channels), the mapping is undefined, so the library throws CImgArgumentException including the texture's (w,h,d,s,ptr).","triggerScenarios":"Calling draw_triangle(x0,y0,x1,y1,x2,y2,texture,tx0,ty0,...) with a 3D (depth>1) texture, or a grayscale texture when drawing into an RGB(A) image, or an empty texture.","commonSituations":"Passing an RGB image instance but a single-channel texture; accidentally passing the whole texture atlas volume instead of a slice; texture image not converted (e.g. L vs RGB) after loading.","solutions":["Convert the texture to match: texture.resize(-100,-100,1,img._spectrum) before drawing","If the texture is 3D, select a slice: texture.get_slice(z) and pass that","Use channel_append/resize to add missing channels to a grayscale texture","Check texture._depth==1 && texture._spectrum>=img._spectrum before calling"],"exampleFix":"// before\nCImg<unsigned char> tex = atlas.get_slice(z); tex = gray; // spectrum 1\nimg.draw_triangle(x0,y0,x1,y1,x2,y2,tex,tx0,ty0,tx1,ty1,tx2,ty2); // img is RGB\n// after\nCImg<unsigned char> tex = atlas.get_slice(z);\ntex.resize(-100,-100,1,img._spectrum); // now 3 channels\nimg.draw_triangle(x0,y0,x1,y1,x2,y2,tex,tx0,ty0,tx1,ty1,tx2,ty2);","handlingStrategy":"validation","validationCode":"if (!texture.is_empty() && texture._depth==1 && texture._spectrum>=img._spectrum) { img.draw_triangle(x0,y0,x1,y1,x2,y2,texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness); }","typeGuard":"template<typename T,typename U> bool validTexture(const CImg<T>& tex, const CImg<U>& img) { return tex._depth==1 && tex._spectrum>=img._spectrum && !tex.is_empty(); }","tryCatchPattern":"try { img.draw_triangle(x0,y0,x1,y1,x2,y2,texture,tx0,ty0,tx1,ty1,tx2,ty2,opacity,brightness); } catch (const CImgArgumentException& e) { /* convert texture and retry */ }","preventionTips":["Normalize all textures to the render target's channel count at load time","Slice volumetric textures before use: get_slice(z)","Keep textures in a fixed format (e.g. RGBA) throughout the pipeline","Check is_overlapped(texture) awareness — the library auto-copies, but shape must still be valid"],"tags":["cimg","texture","dimension-mismatch","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"}