Yalantis/uCrop · error · CImgIOException

load_pnm(): PNM type 'P%d' found, but type is not supported.

Error message

load_pnm(): PNM type 'P%d' found, but type is not supported.

What it means

load_pnm() supports a fixed set of PNM subtypes (P1-P6 etc.) in its switch statement. If the parsed magic number corresponds to a type CImg does not implement (e.g. some P7/PAM variants or invalid digits), the default branch assigns() (empties the image) and throws CImgIOException naming the unsupported type.

Source

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

          for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++);
        }
      } break;
      case 9 : { // 2D/3D grey binary with float values (PINK extension)
        CImg<floatT> raw;
        assign(W,H,D,1);
        T *ptrd = data(0,0,0,0);
        for (longT to_read = (longT)size(); to_read>0; ) {
          raw.assign(std::min(to_read,cimg_iobuffer));
          cimg::fread(raw._data,raw._width,nfile);
          to_read-=raw._width;
          const float *ptrs = raw._data;
          for (ulongT off = (ulongT)raw._width; off; --off) *(ptrd++) = (T)*(ptrs++);
        }
      } break;
      default :
        assign();
        if (!file) cimg::fclose(nfile);
        throw CImgIOException(_cimg_instance
                              "load_pnm(): PNM type 'P%d' found, but type is not supported.",
                              cimg_instance,
                              filename?filename:"(FILE*)",ppm_type);
      }
      if (!file) cimg::fclose(nfile);
      return *this;
    }

    //! Load image from a PFM file.
    /**
      \param filename Filename, as a C-string.
    **/
    CImg<T>& load_pfm(const char *const filename) {
      return _load_pfm(0,filename);
    }

    //! Load image from a PFM file \newinstance.
    static CImg<T> get_load_pfm(const char *const filename) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Convert the file to a supported type: `convert file.pam out.ppm` or `pamtopnm` before loading.
  2. Use load_pnm only for P1-P6; use another loader for PAM/P7 data.
  3. Check the magic bytes ('head -c 2') and confirm the type is one CImg supports in your version.
  4. Upgrade CImg to a newer version that may support more PNM subtypes.
  5. Catch CImgIOException and fall back to an external library (Netpbm, ImageMagick) for exotic types.

Example fix

// before
img.load_pnm("capture.pam"); // P7 not supported
// after
if (firstTwoBytes(path) == "P7") {
  std::system("pamtopnm capture.pam > capture.pnm");
}
img.load_pnm("capture.pnm");
Defensive patterns

Strategy: try-catch

Validate before calling

bool pnmTypeSupported(const char* path) {
  std::ifstream f(path, std::ios::binary);
  char m[2] = {0}; f.read(m, 2);
  return m[0]=='P' && m[1]>='1' && m[1]<='6';
}

Type guard

bool isSupportedPnmType(char t) { return t >= '1' && t <= '6'; }

Try / catch

try {
  img.load_pnm(path);
} catch (cimg_library::CImgIOException& e) {
  std::cerr << "Unsupported PNM type, convert first: " << e.what() << "\n";
  // fallback: shell out to pamtopnm / ImageMagick
}

Prevention

When it happens

Trigger: Loading a PNM file whose 'P<type>' magic is outside the supported switch cases: P7/PAM files, corrupt magic digits like 'P8'/'P9', or a magic token that sscanf parsed into an unexpected ppm_type value.

Common situations: Trying to load Netpbm PAM (P7) files with an older CImg version; corrupted first bytes changing 'P3' to 'P8'; custom tools emitting nonstandard PNM types.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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