Yalantis/uCrop · warning
load_tiff(): File '%s' contains %u image(s) while specified
Error message
load_tiff(): File '%s' contains %u image(s) while specified frame range is [%u,%u] (step %u).
What it means
load_tiff() emits this cimg::warn (non-fatal) when the requested frame range does not fit the actual number of images/directories stored in the TIFF file. The library counts the TIFF directories and, if nfirst_frame is beyond the last frame (or nlast_frame is), warns and then clamps nlast_frame or returns an empty image. It indicates the load will not return what was asked for.
Source
Thrown at ucrop/src/main/jni/CImg.h:58005
#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);
if (nfirst_frame>=nb_images) return assign();
if (nlast_frame>=nb_images) nlast_frame = nb_images - 1;
TIFFSetDirectory(tif,0);
CImg<T> frame;
for (unsigned int l = nfirst_frame; l<=nlast_frame; l+=nstep_frame) {
frame._load_tiff(tif,l,bits_per_value,voxel_size,description);
if (l==nfirst_frame)
assign(frame._width,frame._height,1 + (nlast_frame - nfirst_frame)/nstep_frame,frame._spectrum);
if (frame._width>_width || frame._height>_height || frame._spectrum>_spectrum)
resize(std::max(frame._width,_width),
std::max(frame._height,_height),-100,
std::max(frame._spectrum,_spectrum),0);
draw_image(0,0,(l - nfirst_frame)/nstep_frame,frame);
}View on GitHub (pinned to f788b534b4)
Solutions
- Check the frame count first (e.g. via CImg::load_tiff with a probe or a TIFF library call) and clamp nfirst_frame/nlast_frame to nb_images-1.
- Use ~0U (default) for nlast_frame instead of a hardcoded count so the library clamps automatically.
- Remember frame indices are 0-based; subtract 1 from any 1-based index.
- Re-export the source TIFF with the expected number of pages if the data itself is wrong.
Example fix
// before
img.load_tiff("scan.tif", 0, 9); // assumes 10 pages
// after
unsigned int nb = 0; { TIFF* t = TIFFOpen("scan.tif","r"); do ++nb; while (TIFFReadDirectory(t)); TIFFClose(t); }
img.load_tiff("scan.tif", 0, nb ? nb-1 : ~0U); Defensive patterns
Strategy: validation
Validate before calling
unsigned int nb = 0;
{ /* count TIFF directories before loading */ }
if (nfirst >= nb || (nlast != ~0U && nlast >= nb)) clamp_or_throw(); Type guard
bool frameRangeValid(unsigned first, unsigned last, unsigned nb) { return first < nb && (last == ~0U || last < nb); } Prevention
- Treat cimg warnings as log output and monitor them in CI for image pipelines.
- Use ~0U for nlast_frame unless you know the exact page count.
- Remember frame indices are 0-based.
- Verify TIFF page counts when source files are regenerated.
When it happens
Trigger: Calling CImg::load_tiff(filename, nfirst_frame, nlast_frame, nstep_frame) where nb_images counted via TIFFReadDirectory is smaller than the requested range: nfirst_frame>=nb_images, or nlast_frame!=~0U and nlast_frame>=nb_images.
Common situations: Hardcoded frame indices after the source TIFF was regenerated with fewer pages; multi-page scans truncated; off-by-one assuming frames are 1-based when load_tiff is 0-based; iterating a directory of TIFFs with varying page counts.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- load(): Failed to open file '%s'.
- load(): Failed to recognize format of file '%s'.
- load_bmp(): Invalid offset %d specified in filename '%s'.
- load_bmp(): File size %lu for filename '%s' does not match e
- load_bmp(): Malformed header in filename '%s'.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/1a86c75369726e23.
Report an issue: GitHub.