Yalantis/uCrop · error · CImgInstanceException
cross(): Instance and/or specified image (%u,%u,%u,%u,%p) ar
Error message
cross(): Instance and/or specified image (%u,%u,%u,%u,%p) are not 3D vectors.
What it means
CImg::cross() computes the cross product treating the instance and the argument as 3D vectors, which requires both to be column-ish vectors of width 1 and height>=3. The library throws CImgInstanceException naming the offending image's dimensions when either operand violates this.
Source
Thrown at ucrop/src/main/jni/CImg.h:32805
return *this;
}
return get_transpose().move_to(*this);
}
//! Transpose the image, viewed as a matrix \newinstance.
CImg<T> get_transpose() const {
return get_permute_axes("yxzc");
}
//! Compute the cross product between two \c 1x3 images, viewed as 3D vectors.
/**
\param img Image used as the second argument of the cross product.
\note The first argument of the cross product is \c *this.
**/
template<typename t>
CImg<T>& cross(const CImg<t>& img) {
if (_width!=1 || _height<3 || img._width!=1 || img._height<3)
throw CImgInstanceException(_cimg_instance
"cross(): Instance and/or specified image (%u,%u,%u,%u,%p) are not 3D vectors.",
cimg_instance,
img._width,img._height,img._depth,img._spectrum,img._data);
const T x = (*this)[0], y = (*this)[1], z = (*this)[2];
(*this)[0] = (T)(y*img[2] - z*img[1]);
(*this)[1] = (T)(z*img[0] - x*img[2]);
(*this)[2] = (T)(x*img[1] - y*img[0]);
return *this;
}
//! Compute the cross product between two \c 1x3 images, viewed as 3D vectors \newinstance.
template<typename t>
CImg<_cimg_Tt> get_cross(const CImg<t>& img) const {
return CImg<_cimg_Tt>(*this).cross(img);
}
//! Invert the instance image, viewed as a matrix.View on GitHub (pinned to f788b534b4)
Solutions
- Ensure both operands have shape (1,3): assign(w,h) as img.assign(1,3).
- Transpose a 1x3 row vector: a.get_transpose().cross(b).
- Use a 3-element constructor: CImg<float> v(1,3,1,1, x,y,z).
Example fix
// before CImg<float> a(3,1,1,1,1,0,0), b(3,1,1,1,0,1,0); // row vectors a.cross(b); // throws // after CImg<float> a(1,3,1,1,1,0,0), b(1,3,1,1,0,1,0); a.cross(b);
Defensive patterns
Strategy: validation
Validate before calling
if (a.width()!=1 || a.height()<3 || b.width()!=1 || b.height()<3) throw std::runtime_error("cross() operands must be 1x3 vectors"); Type guard
bool isVec3(const CImg<T>& v){ return v.width()==1 && v.height()>=3; } Try / catch
try { a.cross(b); } catch (CImgInstanceException& e) { std::cerr << e.what() << '\n'; } Prevention
- Store 3D vectors as CImg<T>(1,3) column vectors in CImg
- Transpose 1x3 row vectors before cross()
- Do not pass plain images to vector operations
When it happens
Trigger: Calling a.cross(b) where a or b has width!=1, or height<3 (e.g. row vectors 1x3, 2D points of height 2, or full 2D matrices).
Common situations: Storing vectors as 1x3 row vectors (CImg convention is width=1, height=3 for a column vector); using 2-element 2D points; accidentally passing an image instead of a vector.
Related errors
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Array brackets
- [cimg_appname_math_parser] CImg<%s>::%s: Out-of-bounds refer
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Input vector si
- det(): Instance is not a square matrix.
- invert(): Instance is not a matrix.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/21f2a3b7d087ed3a.
Report an issue: GitHub.