Yalantis/uCrop · error · CImgIOException

load_pnm(): Specified image dimensions in file '%s' exceed f

Error message

load_pnm(): Specified image dimensions in file '%s' exceed file size.

What it means

load_pnm() validates that the declared image volume (W*H*D pixels) does not exceed the actual file size, because PNM raster data is at least one byte per sample. When the header claims more data than the file contains, the library refuses to load and throws CImgIOException instead of reading past EOF or allocating absurd buffers.

Source

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

                              cimg_instance,
                              filename?filename:"(FILE*)");
      }
      if (ppm_type!=1 && ppm_type!=4) {
        if (err==2 || (err==3 && (ppm_type==5 || ppm_type==7 || ppm_type==8 || ppm_type==9))) {
          while ((err=std::fscanf(nfile," %16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile);
          if (cimg_sscanf(item,"%u",&colormax)!=1)
            cimg::warn(_cimg_instance
                       "load_pnm(): COLORMAX field is undefined in file '%s'.",
                       cimg_instance,
                       filename?filename:"(FILE*)");
        } else { colormax = D; D = 1; }
      }
      std::fgetc(nfile);

      if (filename) { // Check that dimensions specified in file does not exceed the buffer dimension
        const cimg_int64 siz = cimg::fsize(filename);
        if (W*H*D>siz)
          throw CImgIOException(_cimg_instance
                                "load_pnm(): Specified image dimensions in file '%s' exceed file size.",
                                cimg_instance,
                                filename);
      }

      switch (ppm_type) {
      case 1 : { // 2D B&W ascii
        assign(W,H,1,1);
        T* ptrd = _data;
        cimg_foroff(*this,off) { if (std::fscanf(nfile,"%d",&rval)>0) *(ptrd++) = (T)(rval?0:255); else break; }
      } break;
      case 2 : { // 2D grey ascii
        assign(W,H,1,1);
        T* ptrd = _data;
        cimg_foroff(*this,off) { if (std::fscanf(nfile,"%d",&rval)>0) *(ptrd++) = (T)rval; else break; }
      } break;
      case 3 : { // 2D color ascii
        assign(W,H,1,3);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check the file size against the expected data size (W*H*D*channels) and re-transfer if truncated.
  2. Correct the width/height in the header to match the actual raster data present.
  3. Regenerate the PNM with a complete write (flush/close after raster data).
  4. Compute expected size in the caller with cimg::fsize() or std::filesystem::file_size before loading and reject short files.
  5. Catch CImgIOException and surface 'corrupt/truncated PNM' to the user.

Example fix

// before
img.load_pnm(path); // throws when header dims exceed file size
// after
auto siz = (long long)std::filesystem::file_size(path);
if (w * h * d <= siz) {
  img.load_pnm(path);
} else {
  throw std::runtime_error("truncated PNM file");
}
Defensive patterns

Strategy: validation

Validate before calling

bool pnmSizePlausible(const char* path, unsigned W, unsigned H, unsigned D) {
  auto siz = (long long)std::filesystem::file_size(path);
  return (long long)W * H * D <= siz;
}

Type guard

bool dimsFitFile(long long fileSize, long long W, long long H, long long D) {
  return W > 0 && H > 0 && D > 0 && W * H * D <= fileSize;
}

Try / catch

try {
  img.load_pnm(path);
} catch (cimg_library::CImgIOException& e) {
  std::cerr << "Corrupt/truncated PNM: " << e.what() << "\n";
}

Prevention

When it happens

Trigger: Loading a PNM whose header dimensions are larger than the file's actual byte size via fsize() check: truncated file, hand-edited dimensions, wrong dimensions in a generator, or a header-only placeholder file.

Common situations: Interrupted downloads/uploads; log or test fixtures edited by hand; generated PNMs where the writer wrote header dimensions but crashed before writing the raster data; sparse placeholder files.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


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