Yalantis/uCrop · error · CImgArgumentException

draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).

Error message

draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).

What it means

In the draw_spline(points,tangents,...) overload, each point must have at least 2 coordinates (points._height>=2); height 0 or 1 means points carry no 2D position and cannot define a spline, so CImgArgumentException is thrown with the points image dimensions and data pointer. Note the guard returns silently for empty/null/width<2 inputs; only height 0/1 with otherwise valid sizes throws.

Source

Thrown at ucrop/src/main/jni/CImg.h:50536

       \param points Vertices data.
       \param tangents Tangents data.
       \param color Pointer to \c spectrum() consecutive values of type \c T, defining the drawing color.
       \param opacity Drawing opacity.
       \param is_closed_set Tells if the drawn spline set is closed.
       \param precision Precision of the drawing.
       \param pattern An integer whose bits describe the line pattern.
       \param init_hatch If \c true, init hatch motif.
    **/
    template<typename tp, typename tt, typename tc>
    CImg<T>& draw_spline(const CImg<tp>& points, const CImg<tt>& tangents,
                         const tc *const color, const float opacity=1,
                         const bool is_closed_set=false, const float precision=4,
                         const unsigned int pattern=~0U, const bool init_hatch=true) {
      if (is_empty() || !points || !tangents || points._width<2 || tangents._width<2) return *this;
      bool ninit_hatch = init_hatch;
      switch (points._height) {
      case 0 : case 1 :
        throw CImgArgumentException(_cimg_instance
                                    "draw_spline(): Invalid specified point set (%u,%u,%u,%u,%p).",
                                    cimg_instance,
                                    points._width,points._height,points._depth,points._spectrum,points._data);

      default : {
        const int x0 = (int)points(0,0), y0 = (int)points(0,1);
        const float u0 = (float)tangents(0,0), v0 = (float)tangents(0,1);
        int ox = x0, oy = y0;
        float ou = u0, ov = v0;
        for (unsigned int i = 1; i<points._width; ++i) {
          const int x = (int)points(i,0), y = (int)points(i,1);
          const float u = (float)tangents(i,0), v = (float)tangents(i,1);
          draw_spline(ox,oy,ou,ov,x,y,u,v,color,precision,opacity,pattern,ninit_hatch);
          ninit_hatch = false;
          ox = x; oy = y; ou = u; ov = v;
        }
        if (is_closed_set) draw_spline(ox,oy,ou,ov,x0,y0,u0,v0,color,precision,opacity,pattern,false);
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure points is Wx2 (or Wx3 with z) with height>=2 before calling.
  2. Transpose or reshape the points image: points.get_transpose() or assign(width,2,...).
  3. Verify tangents has matching width>=2 and height>=2 as well.
  4. Skip the call when points data is degenerate (guard in caller).

Example fix

// before
CImg<float> pts(10,1); // height 1
img.draw_spline(pts,tangents,color,1,false);
// after
CImg<float> pts(10,2); // rows: x[], y[]
img.draw_spline(pts,tangents,color,1,false);
Defensive patterns

Strategy: validation

Validate before calling

if (points.height()<2 || tangents.height()<2) {
  throw std::invalid_argument("spline points/tangents need >=2 rows (x,y per point)");
}
img.draw_spline(points, tangents, color, opacity, is_closed_set);

Type guard

template<typename T> bool isSplinePointSet(const CImg<T>& pts, const CImg<T>& tan) {
  return pts.height()>=2 && tan.height()>=2 && pts.width()>=2 && tan.width()>=2;
}

Try / catch

try {
  img.draw_spline(points, tangents, color, opacity, closed);
} catch (const cimg_library::CImgArgumentException& e) {
  std::fprintf(stderr, "draw_spline points: %s\n", e.what());
}

Prevention

When it happens

Trigger: Passing a points image of dimension Wx1 (one coordinate per point, e.g. only x values) or an empty-height set while width>=2 and tangents._width>=2.

Common situations: Storing points as a single-row vector; a transposition bug producing 1-row matrices; generated point sets from numeric code that collapsed rows.

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


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/bb8ac49faafd941a. Report an issue: GitHub.