Yalantis/uCrop · error · CImgArgumentException

load_video() : File '%s', arguments 'first_frame', 'last_fra

Error message

load_video() : File '%s', arguments 'first_frame', 'last_frame' and 'step_frame' requires features from the OpenCV library ('-Dcimg_use_opencv' must be defined).

What it means

CImgList::load_video() throws this CImgArgumentException when the frame-selection arguments first_frame, last_frame or step_frame are used with values other than their defaults, but the library was compiled without OpenCV support. Frame-range video seeking is only implemented through the OpenCV cv::VideoCapture backend, guarded by the 'cimg_use_opencv' compile-time define. Without it, load_video falls back to an external ffmpeg call that can only decode the whole video from frame 0.

Source

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

      if (!file) cimg::fclose(nfile);
      return *this;
    }

    //! Load an image from a video file, using OpenCV library.
    /**
      \param filename Filename, as a C-string.
      \param first_frame Index of the first frame to read.
      \param last_frame Index of the last frame to read (can be higher than the actual number of frames, e.g. '~0U').
      \param step_frame Step value for frame reading.
      \note If step_frame==0, the current video stream is forced to be released (without any frames read).
    **/
    CImgList<T>& load_video(const char *const filename,
                            const unsigned int first_frame=0, const unsigned int last_frame=~0U,
                            const unsigned int step_frame=1) {
#ifndef cimg_use_opencv
      if (first_frame || last_frame!=~0U || step_frame>1)
        throw CImgArgumentException(_cimglist_instance
                                    "load_video() : File '%s', arguments 'first_frame', 'last_frame' "
                                    "and 'step_frame' requires features from the OpenCV library "
                                    "('-Dcimg_use_opencv' must be defined).",
                                    cimglist_instance,filename);
      return load_ffmpeg_external(filename);
#else
      static cv::VideoCapture *captures[32] = {};
      static CImgList<charT> filenames(32);
      static CImg<uintT> positions(32,1,1,1,0);
      static int last_used_index = -1;

      // Detect if a video capture already exists for the specified filename.
      cimg::mutex(9);
      int index = -1;
      if (filename) {
        if (last_used_index>=0 && !std::strcmp(filename,filenames[last_used_index])) {
          index = last_used_index;
        } else cimglist_for(filenames,l) if (filenames[l] && !std::strcmp(filename,filenames[l])) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Compile the native code with -Dcimg_use_opencv and link against OpenCV (libopencv_videoio) so load_video can use cv::VideoCapture.
  2. If OpenCV support cannot be added, call load_video(filename) with default arguments (0, ~0U, 1) to load the whole video, then slice the frames in memory.
  3. Decode with an external tool beforehand (e.g. ffmpeg -vf select) into images, then load those with CImg instead of relying on frame-range arguments.

Example fix

// before
CImgList<unsigned char> frames;
frames.load_video("clip.mp4", 10, 50, 2); // throws without cimg_use_opencv

// after
CImgList<unsigned char> frames;
frames.load_video("clip.mp4");            // decode all frames
for (unsigned int i = 10; i <= 50 && i < frames.size(); i += 2) {
  CImg<unsigned char> f = frames[i]; // slice in memory
}
Defensive patterns

Strategy: validation

Validate before calling

#ifndef cimg_use_opencv
// frame-range args unsupported: only call with defaults
bool canUseFrameRange = false;
#else
bool canUseFrameRange = true;
#endif
if (!canUseFrameRange && (first || last != ~0U || step > 1)) {
  // avoid frame-range arguments; use defaults
}

Type guard

bool frameRangeSupported() {
#ifdef cimg_use_opencv
  return true;
#else
  return false;
#endif
}

Try / catch

try {
  list.load_video(file, first, last, step);
} catch (CImgArgumentException&) {
  list.load_video(file); // whole-video fallback
  // slice frames manually
}

Prevention

When it happens

Trigger: Calling load_video(filename, first_frame>0) or with last_frame != ~0U or step_frame > 1 on a CImg build compiled without cimg_use_opencv (the default for a bare CImg.h drop-in).

Common situations: Developers copy CImg.h into an Android NDK jni folder (like ucrop does) without enabling OpenCV in the build, then try to extract a sub-range of frames from a video; or they upgrade CImg and the OpenCV define used previously is no longer set in CMake/ndk-build flags.

Related errors


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