Yalantis/uCrop · error · CImgArgumentException
CImg< >::streamline(): Invalid specified integration length…
Error message
CImg<%s>::streamline(): Invalid specified integration length %g (should be >0).
What it means
CImg<T>::streamline() validates the integration step length dl and throws CImgArgumentException if dl<=0, since a positive step is required for the RK-style integration. It also silently returns an empty image if the total length L<=0 or the seed point lies outside the optional bounding box.
Solutions
- Pass a strictly positive dl (e.g. 0.1, the default) to streamline().
- Validate/normalize the step length before the call: if (dl <= 0) dl = 0.1f; or throw your own descriptive error.
- Also ensure L > 0 and the seed point is inside the bounding box (x0..x1, y0..y1, z0..z1) when using the bounded variant, otherwise the call silently returns an empty image.
- Derive dl defensively, e.g. dl = L / std::max(1u, nb_steps), to avoid division producing 0 or negative values.
Example fix
// before float dl = L / steps; // steps could be 0 img.streamline(func, x, y, z, L, dl); // after float dl = steps > 0 ? L / steps : 0.1f; if (dl <= 0) dl = 0.1f; img.streamline(func, x, y, z, L, dl);
Defensive patterns
Strategy: validation
Validate before calling
if (!(dl > 0)) throw std::invalid_argument("streamline dl must be > 0");
if (!(L > 0)) throw std::invalid_argument("streamline L must be > 0"); Try / catch
try { img.streamline(func, x, y, z, L, dl); }
catch (CImgArgumentException& e) { /* clamp dl to 0.1f and retry */ } Prevention
- Validate user-supplied step lengths before integration
- Guard divisions that compute dl (steps >= 1)
- Check the returned image is non-empty when using the bounded variant
When it happens
Trigger: Calling the functor-based streamline(...) overload with dl=0, a negative dl, or NaN, e.g. passing a user-supplied step length without validation.
Common situations: Computing dl from a user parameter or a division (e.g. L/steps with steps=0 or negative) that yields 0 or negative values; configuration default of 0 meaning 'unset'; float precision pushing dl to 0.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- "[" cimg_appname "_math_parser] CImg<
- deriche(): Invalid specified axis '%c'.
- deriche(): Invalid specified order
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/c5c59b6b74c0280b.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:41329
\param is_backward_tracking Tells if the streamline is estimated forward or backward.
\param is_oriented_only Tells if the direction of the vectors must be ignored.
\param x0 X-coordinate of the first bounding-box vertex.
\param y0 Y-coordinate of the first bounding-box vertex.
\param z0 Z-coordinate of the first bounding-box vertex.
\param x1 X-coordinate of the second bounding-box vertex.
\param y1 Y-coordinate of the second bounding-box vertex.
\param z1 Z-coordinate of the second bounding-box vertex.
**/
template<typename tfunc>
static CImg<floatT> streamline(const tfunc& func,
const float x, const float y, const float z,
const float L=256, const float dl=0.1f,
const unsigned int interpolation_type=2, const bool is_backward_tracking=false,
const bool is_oriented_only=false,
const float x0=0, const float y0=0, const float z0=0,
const float x1=0, const float y1=0, const float z1=0) {
if (dl<=0)
throw CImgArgumentException("CImg<%s>::streamline(): Invalid specified integration length %g "
"(should be >0).",
pixel_type(),
dl);
const bool is_bounded = (x0!=x1 || y0!=y1 || z0!=z1);
if (L<=0 || (is_bounded && (x<x0 || x>x1 || y<y0 || y>y1 || z<z0 || z>z1))) return CImg<floatT>();
const unsigned int size_L = (unsigned int)cimg::round(L/dl + 1);
CImg<floatT> coordinates(size_L,3);
const float dl2 = dl/2;
float
*ptr_x = coordinates.data(0,0),
*ptr_y = coordinates.data(0,1),
*ptr_z = coordinates.data(0,2),
pu = (float)(dl*func(x,y,z,0)),
pv = (float)(dl*func(x,y,z,1)),
pw = (float)(dl*func(x,y,z,2)),
X = x, Y = y, Z = z;
View on GitHub (pinned to f788b534b4)