Yalantis/uCrop · error · CImgArgumentException
load_tiff(): Unable to read sub-images from file '%s' unless
Error message
load_tiff(): Unable to read sub-images from file '%s' unless libtiff is enabled.
What it means
When CImg is built without libtiff (cimg_use_tiff undefined), load_tiff() can only load a single-image file via load_other(). If the caller requests any sub-image selection (non-zero first_frame, a bounded last_frame, or step_frame > 1), the library refuses with this argument error because multi-frame reading requires libtiff.
Source
Thrown at ucrop/src/main/jni/CImg.h:57990
**/
CImg<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) {
if (!filename)
throw CImgArgumentException(_cimg_instance
"load_tiff(): Specified filename is (null).",
cimg_instance);
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(_cimg_instance
"load_tiff(): Unable to read sub-images from file '%s' unless libtiff is enabled.",
cimg_instance,
filename);
return load_other(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(_cimg_instance
"load_tiff(): File '%s' contains %u image(s) while specified frame range is [%u,%u] (step %u).",
cimg_instance,
filename,nb_images,nfirst_frame,nlast_frame,nstep_frame);View on GitHub (pinned to f788b534b4)
Solutions
- Build CImg with cimg_use_tiff defined and link against libtiff to enable multi-frame reads.
- If single-image loading suffices, call load_tiff(filename) with default frame arguments (0, ~0U, 1).
- Pre-decode the TIFF with another library and pass raw data to CImg.
Example fix
// before (no libtiff build)
img.load_tiff("stack.tif", 3);
// after: default args work without libtiff
img.load_tiff("stack.tif"); Defensive patterns
Strategy: fallback
Validate before calling
#ifndef cimg_use_tiff
if (firstFrame != 0 || stepFrame > 1) throw std::logic_error("sub-image reads need libtiff build");
#endif Try / catch
try { img.load_tiff(f, frame); }
catch (CImgArgumentException &e) { img.load_tiff(f); /* single-image fallback */ } Prevention
- Define cimg_use_tiff and link libtiff when multi-page TIFFs are expected
- Use default frame arguments when only the first image is needed
- Document build requirements next to the loader calls
When it happens
Trigger: img.load_tiff("file.tif", 2) or load_tiff("f.tif", 0, 5) or load_tiff("f.tif", 0, ~0U, 2) compiled without cimg_use_tiff.
Common situations: Building the Android/JNI project without libtiff linked, then attempting to read a specific page of a multi-page TIFF stack; a build that previously had libtiff was rebuilt without it.
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
- CImgDisplay(): No display available.
- load_jpeg(): Unable to load data from '(FILE*)' unless libjp
- load_jxl(): Unable to load data from '(FILE*)' unless libjxl
- load_png(): Unable to load data from '(FILE*)' unless libpng
- load_tiff(): Specified filename is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/6e6c40c0bc17ebf8.
Report an issue: GitHub.