Yalantis/uCrop · error · CImgIOException

load_tiff(): Invalid tile in file '%s'.

Error message

load_tiff(): Invalid tile in file '%s'.

What it means

When a TIFF is stored as tiles (single sample per pixel), load_tiff() reads each tile with TIFFReadTile(). A negative return means the tile data is corrupt, truncated, or inconsistent with the directory, so the library throws a CImgIOException and closes the file.

Source

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

                                 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) {
      return CImg<T>().load_tiff(filename,first_frame,last_frame,step_frame,bits_per_value,voxel_size,description);
    }

    // (Original contribution by Jerome Boulanger).
#ifdef cimg_use_tiff
    template<typename t>
    void _load_tiff_tiled_contig(TIFF *const tif, const cimg_uint16 samplesperpixel,
                                 const cimg_uint32 nx, const cimg_uint32 ny,
                                 const cimg_uint32 tw, const cimg_uint32 th) {
      t *const buf = (t*)_TIFFmalloc(TIFFTileSize(tif));
      if (buf) {
        for (unsigned int row = 0; row<ny; row+=th)
          for (unsigned int col = 0; col<nx; col+=tw) {
            if (TIFFReadTile(tif,buf,col,row,0,0)<0) {
              _TIFFfree(buf); TIFFClose(tif);
              throw CImgIOException(_cimg_instance
                                    "load_tiff(): Invalid tile in file '%s'.",
                                    cimg_instance,
                                    TIFFFileName(tif));
            }
            const t *ptr = buf;
            for (unsigned int rr = row; rr<std::min((unsigned int)(row + th),(unsigned int)ny); ++rr)
              for (unsigned int cc = col; cc<std::min((unsigned int)(col + tw),(unsigned int)nx); ++cc)
                for (unsigned int vv = 0; vv<samplesperpixel; ++vv)
                  (*this)(cc,rr,vv) = (T)(ptr[(rr - row)*th*samplesperpixel + (cc - col)*samplesperpixel + vv]);
          }
        _TIFFfree(buf);
      }
    }

    template<typename t>
    void _load_tiff_tiled_separate(TIFF *const tif, const cimg_uint16 samplesperpixel,
                                   const cimg_uint32 nx, const cimg_uint32 ny,
                                   const cimg_uint32 tw, const cimg_uint32 th) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Re-acquire or re-export the TIFF from a trusted source/encoder.
  2. Validate the file with tiffinfo/tiffcp to locate corrupt tiles.
  3. Re-save the image as strip-based or uncompressed TIFF, then reload.
  4. Catch CImgIOException and fall back to another loader.

Example fix

// before
img.load_tiff("corrupt.tif");
// after: repair first
// $ tiffcp corrupt.tif repaired.tif
img.load_tiff("repaired.tif");
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate: reject suspiciously small files
std::ifstream f(path, std::ios::binary | std::ios::ate);
if (f.tellg() < 256) throw std::runtime_error("TIFF too small / truncated");

Try / catch

try { img.load_tiff(path); }
catch (CImgIOException &e) { log("tiled TIFF corrupt; repair with tiffcp"); fallbackLoader(path); }

Prevention

When it happens

Trigger: Loading a tiled TIFF whose tile data is truncated, corrupted by a partial transfer/download, or written with a broken encoder.

Common situations: Incomplete uploads of TIFF files, files damaged in transit, or TIFFs produced by buggy third-party encoders.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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