{"record":{"id":"a2654b2d3382b190","repo":"Yalantis/uCrop","slug":"draw-triangle-invalid-specified-light-texture","errorCode":null,"errorMessage":"draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).","messagePattern":"draw_triangle\\(\\): Invalid specified light texture \\(%u,%u,%u,%u,%p\\)\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":51359,"sourceCode":"       \\param opacity Drawing opacity.\n    **/\n    template<typename tc, typename tl>\n    CImg<T>& draw_triangle(int x0, int y0,\n                           int x1, int y1,\n                           int x2, int y2,\n                           const tc *const color,\n                           const CImg<tl>& light,\n                           int lx0, int ly0,\n                           int lx1, int ly1,\n                           int lx2, int ly2,\n                           const float opacity=1) {\n      if (is_empty()) return *this;\n      if (!color)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_triangle(): Specified color is (null).\",\n                                    cimg_instance);\n      if (light._depth>1 || light._spectrum<_spectrum)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_triangle(): Invalid specified light texture (%u,%u,%u,%u,%p).\",\n                                    cimg_instance,light._width,light._height,light._depth,light._spectrum,light._data);\n\n      if (y0>y1) cimg::swap(x0,x1,y0,y1,lx0,lx1,ly0,ly1);\n      if (y0>y2) cimg::swap(x0,x2,y0,y2,lx0,lx2,ly0,ly2);\n      if (y1>y2) cimg::swap(x1,x2,y1,y2,lx1,lx2,ly1,ly2);\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,\n        dlx01 = (longT)lx1 - lx0, dlx02 = (longT)lx2 - lx0, dlx12 = (longT)lx2 - lx1,\n        dly01 = (longT)ly1 - ly0, dly02 = (longT)ly2 - ly0, dly12 = (longT)ly2 - ly1;\n      const ulongT lwhd = (ulongT)light._width*light._height*light._depth;","sourceCodeStart":51341,"sourceCodeEnd":51377,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L51341-L51377","documentation":"draw_triangle() (2D variant) supports a `light` texture argument used for gouraud/textured shading. If the light image has depth > 1 (it is a volume, not a 2D texture) or fewer channels than the drawing image's spectrum, the texture cannot be sampled per-pixel, so CImg throws CImgArgumentException with the light image's dimensions for diagnosis.","triggerScenarios":"Calling draw_triangle(x0,y0,x1,y1,x2,y2,color,lx0..ly2,light,...) where `light` is a 3D (depth>1) image, or light.spectrum() < image.spectrum() (e.g. a grayscale light texture on an RGB image).","commonSituations":"Passing a volumetric image as the light map; reusing a light texture from a grayscale pipeline in a color (spectrum=3) draw; mixing images loaded with different channel counts.","solutions":["Provide a 2D light image (depth == 1) whose spectrum() is >= the target image's spectrum()","Convert the light texture first: light.get_resize(w,h,1,spectrum()) or get_channel(0) expanded to the right channel count","If shading is not needed, omit the light texture (use the overload without light) instead of passing an unsuitable image","Log light._width/_height/_depth/_spectrum (as printed in the message) and fix the mismatch"],"exampleFix":"// before\ndraw_triangle(x0,y0,x1,y1,x2,y2,color,0,0,0,0,0,0,grayLight); // grayLight spectrum=1, image spectrum=3\n// after\nCImg<T> light = grayLight.get_resize(grayLight.width(),grayLight.height(),1,3);\ndraw_triangle(x0,y0,x1,y1,x2,y2,color,0,0,0,0,0,0,light);","handlingStrategy":"validation","validationCode":"if (!light || light.depth() > 1 || light.spectrum() < image.spectrum())\n  light.assign(light.width(),light.height(),1,image.spectrum()); // normalize\nimage.draw_triangle(x0,y0,x1,y1,x2,y2,color,lx0,ly0,lx1,ly1,lx2,ly2,light,opacity);","typeGuard":"bool validLight = (light.depth() == 1 && light.spectrum() >= image.spectrum());","tryCatchPattern":"try { image.draw_triangle(...,light); }\ncatch (cimg_library::CImgArgumentException &e) { log_error(\"light texture invalid: %s\", e.what()); }","preventionTips":["Keep all light textures as single-channel or target-spectrum 2D images by convention","Normalize textures (resize to depth 1, matching spectrum) at load time, not at draw time","Print image.spectrum() and light.spectrum() in debug logs when wiring up textured draws","Avoid passing z-buffers or volumes as light textures"],"tags":["cimg","texture","shape-mismatch","argument-validation"],"backgroundTag":"tensor-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"}