Yalantis/uCrop · error · CImgIOException

load_analyze(): Cannot read header (of size %u) in file '%s'

Error message

load_analyze(): Cannot read header (of size %u) in file '%s'.

What it means

load_analyze() allocates header_size bytes and reads header_size-4 more bytes from the header file. If fread returns fewer bytes than requested, the header file is truncated relative to its own declared sizeof_hdr, and this exception is thrown. It is a short-read/corrupt-file condition.

Source

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

                              "load_analyze(): Invalid Analyze7.5 or NIFTI header in file '%s'.",
                              cimg_instance,
                              filename?filename:"(FILE*)");

      // Read header.
      bool endian = false;
      unsigned int header_size;
      cimg::fread(&header_size,1,nfile_header);
      if (header_size>=4096) { endian = true; cimg::invert_endianness(header_size); }
      if (header_size<128)
        throw CImgIOException(_cimg_instance
                              "load_analyze(): Invalid header size (%u) specified in file '%s'.",
                              cimg_instance,
                              header_size,filename?filename:"(FILE*)");

      unsigned char *const header = new unsigned char[header_size];
      const size_t header_size_read = cimg::fread(header + 4,header_size - 4,nfile_header);
      if (header_size_read!=header_size - 4)
        throw CImgIOException(_cimg_instance
                              "load_analyze(): Cannot read header (of size %u) in file '%s'.",
                              cimg_instance,
                              header_size,filename?filename:"(FILE*)");

      if (!file && nfile_header!=nfile) cimg::fclose(nfile_header);
      if (endian) {
        cimg::invert_endianness((short*)(header + 40),5);
        cimg::invert_endianness((short*)(header + 70),1);
        cimg::invert_endianness((short*)(header + 72),1);
        cimg::invert_endianness((float*)(header + 76),4);
        cimg::invert_endianness((float*)(header + 108),1);
        cimg::invert_endianness((float*)(header + 112),1);
      }

      if (nfile_header==nfile) {
        const unsigned int vox_offset = (unsigned int)*(float*)(header + 108);
        std::fseek(nfile,vox_offset,SEEK_SET);
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Verify the .hdr file size is at least sizeof_hdr bytes (348 for standard Analyze7.5/NIfTI-1) before loading.
  2. Re-transfer/re-export the truncated header file.
  3. Ensure you point load_analyze() at the .img and let it find the matching .hdr, not at the raw data file as the header.
  4. Compare checksums of source and copied headers to detect partial copies.
  5. Catch CImgIOException and skip/re-fetch the offending volume in batch processing.

Example fix

// before
img.load_analyze("t1.img"); // t1.hdr truncated at 200 bytes, claims 348
// after
if (cimg::fsize("t1.hdr") < 348) throw std::runtime_error("t1.hdr truncated");
img.load_analyze("t1.img");
Defensive patterns

Strategy: validation

Validate before calling

bool headerComplete(const char* hdrPath) {
  std::FILE* f = std::fopen(hdrPath, "rb"); if (!f) return false;
  unsigned int h = 0; bool ok = std::fread(&h, 4, 1, f) == 1;
  long size = -1; if (ok) { std::fseek(f, 0, SEEK_END); size = std::ftell(f); }
  std::fclose(f);
  return ok && size >= (long)h; // file at least sizeof_hdr bytes
}

Type guard

bool headerFullyRead(size_t header_size_read, unsigned int header_size) { return header_size_read == header_size - 4; }

Try / catch

try { img.load_analyze(imgPath); }
catch (CImgIOException& e) { fprintf(stderr, "Header short read — re-transfer dataset: %s\n", e.what()); }

Prevention

When it happens

Trigger: Header file whose declared sizeof_hdr (e.g. 348) exceeds the actual file size — truncated download, partially-copied .hdr, or an .img file mistakenly opened as the header.

Common situations: Incomplete dataset transfers (ftp/usb cut off); backup tools skipping files; .hdr and .img pair mixed up so the data file is parsed as a header.

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/46abd04c7b382e61. Report an issue: GitHub.