{"record":{"id":"048454c7bb3bef1e","repo":"Yalantis/uCrop","slug":"draw-line-invalid-specified-texture-u-u-u","errorCode":null,"errorMessage":"draw_line(): Invalid specified texture (%u,%u,%u,%u,%p).","messagePattern":"draw_line\\(\\): Invalid specified texture \\(%u,%u,%u,%u,%p\\)\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":50067,"sourceCode":"       \\par Example:\n       \\code\n       CImg<unsigned char> img(100,100,1,3,0), texture(\"texture256x256.ppm\");\n       const unsigned char color[] = { 255,128,64 };\n       img.draw_line(40,40,80,70,texture,0,0,255,255);\n       \\endcode\n    **/\n    template<typename tc>\n    CImg<T>& draw_line(int x0, int y0,\n                       int x1, int y1,\n                       const CImg<tc>& texture,\n                       int tx0, int ty0,\n                       int tx1, int ty1,\n                       const float opacity=1,\n                       const unsigned int pattern=~0U, const bool init_hatch=true) {\n\n      if (is_empty() || !opacity || !pattern) return *this;\n      if (texture._depth>1 || texture._spectrum<_spectrum)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_line(): 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)) return draw_line(x0,y0,x1,y1,+texture,tx0,ty0,tx1,ty1,opacity,pattern,init_hatch);\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        dtx01 = tx1 - tx0, dty01 = ty1 - ty0;\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,tx0,tx1,ty0,ty1);\n        dx01*=-1; dy01*=-1; dtx01*=-1; dty01*=-1;\n      }\n      const float","sourceCodeStart":50049,"sourceCodeEnd":50085,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L50049-L50085","documentation":"The 2D draw_line() overload with texturing requires the texture image to be 2D (_depth==1) and to have at least as many channels as the target image (_spectrum>=img._spectrum). Passing a volumetric texture (depth>1) or one with too few color channels cannot be sampled correctly, so CImg throws CImgArgumentException.","triggerScenarios":"Calling img.draw_line(x0,y0,x1,y1,texture,tx0,ty0,tx1,ty1) where texture._depth>1 (e.g. a CImg of size w,h,d,c with d>1) or texture._spectrum<img._spectrum — e.g. a single-channel grayscale texture used to draw on an RGB image, or a 3D volume passed as the texture.","commonSituations":"Using a scalar (1-channel) texture against an RGBA/RGB image; accidentally passing a 3D image/volume or a list of slices as the texture; a texture built by concatenation that gained a depth dimension; spectrum mismatch after converting the main image to color but keeping the old texture.","solutions":["Make the texture a 2D image with matching channels: CImg<> texture(tw,th,1,img.spectrum()).","If the texture is grayscale, convert or expand it: texture.resize(tw,th,1,img.spectrum()) or draw on a grayscale image instead.","If the texture is a 3D volume, select a slice first: draw_line(...,texture.get_slice(z),...).","Note: overlapping texture and image is handled internally (copy via +texture), so overlap itself is not the problem — only depth/spectrum is."],"exampleFix":"// before\nCImg<> tex(64,64,8,1); // depth>1 -> throws on RGB img\nimg.draw_line(0,0,50,50,tex,0,0,63,63);\n\n// after\nCImg<> tex(64,64,1,3);\nimg.draw_line(0,0,50,50,tex,0,0,63,63);","handlingStrategy":"validation","validationCode":"if (texture && texture._depth == 1 && texture._spectrum >= img.spectrum()) {\n  img.draw_line(x0,y0,x1,y1,texture,tx0,ty0,tx1,ty1,opacity);\n}","typeGuard":"template<typename t, typename T>\nbool is_valid_texture(const CImg<t>& img, const CImg<T>& tex) {\n  return !tex.is_empty() && tex._depth == 1 && tex._spectrum >= img.spectrum();\n}","tryCatchPattern":"try {\n  img.draw_line(x0,y0,x1,y1,texture,tx0,ty0,tx1,ty1);\n} catch (CImgArgumentException& e) {\n  std::fprintf(stderr, \"bad texture: %s\\n\", e.what());\n}","preventionTips":["Keep textures 2D: build atlases as wide 2D images, not stacked volumes.","Match texture spectrum to the target image spectrum before drawing.","Convert grayscale textures with resize(tw,th,1,img.spectrum()) when drawing on color images.","Use get_slice(z) when the source data is volumetric."],"tags":["cimg","texture","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"}