Yalantis/uCrop · error · CImgArgumentException

load_pnm(): Specified filename is (null).

Error message

load_pnm(): Specified filename is (null).

What it means

CImg's _load_pnm() throws CImgArgumentException when both the FILE* and filename are null — there is no input for the PNM/PPM/PGM loader. This is an argument-validation guard, analogous to the load_png null check.

Solutions

  1. Pass a valid path: img.load_pnm("image.ppm").
  2. Or pass an open FILE*: img.load_pnm(file).
  3. Null-check/configure the source of the filename before calling.

Example fix

// before
const char *p = cfg.get("pnm_path"); // may be NULL
img.load_pnm(p);
// after
const char *p = cfg.get("pnm_path");
if (!p) throw std::runtime_error("pnm_path not configured");
img.load_pnm(p);
Defensive patterns

Strategy: validation

Validate before calling

if (!filename && !file) throw std::invalid_argument("load_pnm requires a filename or FILE*");
img.load_pnm(filename);

Type guard

bool hasSource(const char *f, std::FILE *h) { return f != nullptr || h != nullptr; }

Prevention

When it happens

Trigger: Calling load_pnm(nullptr) / load_pnm((const char*)0), or a wrapper passing an uninitialized/NULL filename with a null FILE* into _load_pnm.

Common situations: Filename built from an unset environment variable or missing config entry; a lookup function returning const char* NULL passed straight to load_pnm.

Related errors


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

Appendix: source

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

    //! Load image from a PNM file \newinstance.
    static CImg<T> get_load_pnm(const char *const filename) {
      return CImg<T>().load_pnm(filename);
    }

    //! Load image from a PNM file \overloading.
    CImg<T>& load_pnm(std::FILE *const file) {
      return _load_pnm(file,0);
    }

    //! Load image from a PNM file \newinstance.
    static CImg<T> get_load_pnm(std::FILE *const file) {
      return CImg<T>().load_pnm(file);
    }

    CImg<T>& _load_pnm(std::FILE *const file, const char *const filename) {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "load_pnm(): Specified filename is (null).",
                                    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) {

View on GitHub (pinned to f788b534b4)