{"record":{"id":"15e665cec3290884","repo":"Yalantis/uCrop","slug":"draw-gaussian-specified-tensor-u-u-u-u-p","errorCode":null,"errorMessage":"draw_gaussian(): Specified tensor (%u,%u,%u,%u,%p) is not a 2x2 matrix.","messagePattern":"draw_gaussian\\(\\): Specified tensor \\(%u,%u,%u,%u,%p\\) is not a 2x2 matrix\\.","errorType":"validation","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":53920,"sourceCode":"        col-=_spectrum;\n      }\n      return *this;\n    }\n\n    //! Draw a 2D gaussian function.\n    /**\n       \\param xc X-coordinate of the gaussian center.\n       \\param yc Y-coordinate of the gaussian center.\n       \\param tensor Covariance matrix (must be 2x2).\n       \\param color Pointer to \\c spectrum() consecutive values, defining the drawing color.\n       \\param opacity Drawing opacity.\n    **/\n    template<typename t, typename tc>\n    CImg<T>& draw_gaussian(const float xc, const float yc, const CImg<t>& tensor,\n                           const tc *const color, const float opacity=1) {\n      if (is_empty()) return *this;\n      if (tensor._width!=2 || tensor._height!=2 || tensor._depth!=1 || tensor._spectrum!=1)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_gaussian(): Specified tensor (%u,%u,%u,%u,%p) is not a 2x2 matrix.\",\n                                    cimg_instance,\n                                    tensor._width,tensor._height,tensor._depth,tensor._spectrum,tensor._data);\n      if (!color)\n        throw CImgArgumentException(_cimg_instance\n                                    \"draw_gaussian(): Specified color is (null).\",\n                                    cimg_instance);\n      typedef typename CImg<t>::Tfloat tfloat;\n      const CImg<tfloat> invT = tensor.get_invert(), invT2 = (invT*invT)/=-2.;\n      const tfloat a = invT2(0,0), b = 2*invT2(1,0), c = invT2(1,1);\n      const float nopacity = cimg::abs(opacity), copacity = 1 - std::max(opacity,0.f);\n      const ulongT whd = (ulongT)_width*_height*_depth;\n      const tc *col = color;\n      float dy = -yc;\n      cimg_forY(*this,y) {\n        float dx = -xc;\n        cimg_forX(*this,x) {\n          const float val = (float)std::exp(a*dx*dx + b*dx*dy + c*dy*dy);","sourceCodeStart":53902,"sourceCodeEnd":53938,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L53902-L53938","documentation":"CImg's draw_gaussian() 2D variant draws a 2D Gaussian bump whose shape is defined by a symmetric 2x2 tensor (covariance) matrix. The library validates that the tensor image has width=2, height=2, depth=1, spectrum=1, and throws CImgArgumentException when it does not. This is an argument-shape validation, thrown before any drawing occurs.","triggerScenarios":"Calling draw_gaussian(xc,yc,tensor,color) with a tensor CImg that is not exactly 2x2x1x1 — e.g. passing a 1x1 matrix, a 3x3 tensor, an image with multiple spectrum channels, or a wrong-sized intermediate result from get_invert/multiplication.","commonSituations":"Building the covariance tensor programmatically and computing its size wrong (e.g. appending rows/columns, accidentally using the full 3x3 tensor of the 3D overload); reusing an image variable that was earlier resized; loading a tensor from a file with extra channels.","solutions":["Construct the tensor explicitly as a 2x2 image: CImg<float> tensor(2,2); tensor = sxx, sxy, sxy, syy;","Verify dimensions before the call: if (tensor.width()!=2 || tensor.height()!=2) throw/log.","Use the 3D draw_gaussian overload's 3x3 tensor only with the 3D overload, and vice versa.","Check that intermediate operations (get_invert, multiplication) did not resize the tensor."],"exampleFix":"// before\nCImg<float> tensor(3,3); // wrong shape\nimg.draw_gaussian(xc, yc, tensor, color);\n// after\nCImg<float> tensor(2,2);\ntensor(0,0)=sxx; tensor(1,0)=sxy; tensor(0,1)=sxy; tensor(1,1)=syy;\nimg.draw_gaussian(xc, yc, tensor, color);","handlingStrategy":"validation","validationCode":"if (tensor.width()!=2 || tensor.height()!=2 || tensor.depth()!=1 || tensor.spectrum()!=1) {\n  throw std::invalid_argument(\"draw_gaussian tensor must be a 2x2 matrix\");\n}","typeGuard":"bool is2x2Tensor(const CImg<float>& t) {\n  return t.width()==2 && t.height()==2 && t.depth()==1 && t.spectrum()==1;\n}","tryCatchPattern":"try {\n  img.draw_gaussian(xc, yc, tensor, color);\n} catch (const cimg_library::CImgArgumentException& e) {\n  std::cerr << \"Bad gaussian tensor: \" << e.what() << std::endl;\n}","preventionTips":["Always allocate the tensor with explicit 2x2 dimensions","Unit-test tensor construction once and reuse a factory function","Keep 2x2 and 3x3 tensors in distinctly named variables"],"tags":["cimg","image-processing","argument-validation","tensor-shape"],"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-17T15:17:12.973Z"}