Yalantis/uCrop · error · CImgIOException

load_pnm(): WIDTH and HEIGHT fields undefined in file

Error message

load_pnm(): WIDTH and HEIGHT fields undefined in file '%s'.

What it means

After reading the PNM magic number, load_pnm() reads the next non-comment line and parses WIDTH, HEIGHT (and optionally DEPTH and COLORMAX) fields. If fewer than 2 unsigned integers are found (cimg_sscanf returns <2), the header is incomplete and the library throws CImgIOException.

Solutions

  1. Open the file and confirm the second header line contains two or more integers (e.g. '640 480').
  2. Fix the generating code/exporter to emit 'width height' after the magic number.
  3. Re-export the image with a standard tool (`convert in.png out.pnm`) to regenerate a valid header.
  4. Check the file was fully written (compare size against expected dimensions); re-download if truncated.
  5. Catch CImgIOException around load_pnm and fall back to another decoder.

Example fix

// before
f << "P6\n";              // header incomplete
// after
f << "P6\n" << width << " " << height << "\n255\n";
Defensive patterns

Strategy: validation

Validate before calling

bool pnmHeaderComplete(const char* path) {
  std::ifstream f(path);
  std::string line1, line2;
  std::getline(f, line1); std::getline(f, line2);
  int a=0, b=0;
  return std::sscanf(line2.c_str(), "%d %d", &a, &b) == 2;
}

Type guard

bool hasTwoInts(const std::string& s) {
  int a, b;
  return std::sscanf(s.c_str(), " %d %d", &a, &b) == 2;
}

Try / catch

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

Prevention

When it happens

Trigger: load_pnm() on a file with a valid 'P<digit>' magic line but missing or malformed width/height fields: header truncated after the magic number, non-numeric text where dimensions should be, extra comment lines not starting with '#' breaking the parser, or a file containing only 'P6'.

Common situations: Hand-written PNM generators that forgot the dimension line; truncation during network transfer or interrupted write; template files with placeholders like 'W H' left unsubstituted.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

                                    cimg_instance);

      std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
      unsigned int ppm_type, W, H, D = 1, colormax = 255;
      CImg<charT> item(16384,1,1,1,0);
      int err, rval, gval, bval;
      const longT cimg_iobuffer = (longT)24*1024*1024;
      while ((err=std::fscanf(nfile,"%16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile);
      if (cimg_sscanf(item," P%u",&ppm_type)!=1) {
        if (!file) cimg::fclose(nfile);
        throw CImgIOException(_cimg_instance
                              "load_pnm(): PNM header not found in file '%s'.",
                              cimg_instance,
                              filename?filename:"(FILE*)");
      }
      while ((err=std::fscanf(nfile," %16383[^\n]",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile);
      if ((err=cimg_sscanf(item," %u %u %u %u",&W,&H,&D,&colormax))<2) {
        if (!file) cimg::fclose(nfile);
        throw CImgIOException(_cimg_instance
                              "load_pnm(): WIDTH and HEIGHT fields undefined in file '%s'.",
                              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);

View on GitHub (pinned to f788b534b4)