Yalantis/uCrop · error · CImgArgumentException

load_tiff(): Unable to load sub-images from file

Error message

load_tiff(): Unable to load sub-images from file '%s' unless libtiff is enabled.

What it means

CImgList::load_tiff() supports loading a subrange of sub-images (frames) only when CImg is compiled with libtiff support (cimg_use_tiff defined). Without libtiff, any request with a frame range or step other than the trivial default throws CImgArgumentException. Only single-image loading via the fallback is possible.

Solutions

  1. Rebuild CImg with cimg_use_tiff defined and link against libtiff.
  2. If rebuilding is not possible, call load_tiff with default frame arguments (single image) and load frames one call at a time.
  3. Decode the TIFF with an external library (e.g. libtiff directly) and populate the CImgList yourself.

Example fix

// before
list.load_tiff("multi.tif", 0, 10); // throws without libtiff
// after
list.load_tiff("multi.tif"); // single-frame fallback, no libtiff needed
// or rebuild with: -Dcimg_use_tiff -ltiff
Defensive patterns

Strategy: fallback

Validate before calling

// load only single-frame ranges unless libtiff support was compiled in
#ifdef cimg_use_tiff
  list.load_tiff(path, first, last, step);
#else
  list.load_tiff(path); // default single-image form
#endif

Try / catch

try { list.load_tiff(path, first, last); }
catch (CImgArgumentException &e) { list.load_tiff(path); /* single-frame fallback */ }

Prevention

When it happens

Trigger: Calling load_tiff(filename, first_frame!=0, ...) or with last_frame/step_frame arguments while the library was built WITHOUT cimg_use_tiff; i.e. requesting multi-frame/sub-image semantics on a libtiff-less build.

Common situations: Prebuilt Android/JNI binaries of CImg compiled without libtiff; app code upgraded to use multi-page TIFFs while the vendored CImg build flags never enabled cimg_use_tiff.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


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

Appendix: source

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

        \param first_frame Index of first image frame to read.
        \param last_frame Index of last image frame to read.
        \param step_frame Step applied between each frame.
        \param[out] bits_per_value Number of bits used to store a scalar value in the image file.
        \param[out] voxel_size Voxel size, as stored in the filename.
        \param[out] description Description, as stored in the filename.
    **/
    CImgList<T>& load_tiff(const char *const filename,
                           const unsigned int first_frame=0, const unsigned int last_frame=~0U,
                           const unsigned int step_frame=1, unsigned int *const bits_per_value=0,
                           float *const voxel_size=0, CImg<charT> *const description=0) {
      const unsigned int
        nfirst_frame = first_frame<last_frame?first_frame:last_frame,
        nstep_frame = step_frame?step_frame:1;
      unsigned int nlast_frame = first_frame<last_frame?last_frame:first_frame;
#ifndef cimg_use_tiff
      cimg::unused(bits_per_value,voxel_size,description);
      if (nfirst_frame || nlast_frame!=~0U || nstep_frame!=1)
        throw CImgArgumentException(_cimglist_instance
                                    "load_tiff(): Unable to load sub-images from file '%s' unless libtiff is enabled.",
                                    cimglist_instance,
                                    filename);

      return assign(CImg<T>::get_load_tiff(filename));
#else
#if cimg_verbosity<3
        TIFFSetWarningHandler(0);
        TIFFSetErrorHandler(0);
#endif
      TIFF *tif = TIFFOpen(filename,"r");
      if (tif) {
        unsigned int nb_images = 0;
        do ++nb_images; while (TIFFReadDirectory(tif));
        if (nfirst_frame>=nb_images || (nlast_frame!=~0U && nlast_frame>=nb_images))
          cimg::warn(_cimglist_instance
                     "load_tiff(): Invalid specified frame range is [%u,%u] (step %u) since "
                     "file '%s' contains %u image(s).",

View on GitHub (pinned to f788b534b4)