Yalantis/uCrop · error · CImgIOException

load_png(): Unable to load data from '(FILE*)' unless libpng

Error message

load_png(): Unable to load data from '(FILE*)' unless libpng is enabled.

What it means

CImg is compiled without cimg_use_png, so libpng support is disabled and the loader can only read from a named file (via the generic load_other path). Reading from a FILE* stream is impossible, so a CImgIOException is thrown.

Source

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

      return _load_png(file,0,bits_per_value);
    }

    //! Load image from a PNG file \newinstance.
    static CImg<T> get_load_png(std::FILE *const file, unsigned int *const bits_per_value=0) {
      return CImg<T>().load_png(file,bits_per_value);
    }

    // (Note: Most of this function has been written by Eric Fausett).
    CImg<T>& _load_png(std::FILE *const file, const char *const filename, unsigned int *const bits_per_value) {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "load_png(): Specified filename is (null).",
                                    cimg_instance);

#ifndef cimg_use_png
      cimg::unused(bits_per_value);
      if (file)
        throw CImgIOException(_cimg_instance
                              "load_png(): Unable to load data from '(FILE*)' unless libpng is enabled.",
                              cimg_instance);

      else return load_other(filename);
#else
      // Open file and check for PNG validity.
#if defined __GNUC__
      const char *volatile nfilename = filename; // Use 'volatile' to avoid (wrong) g++ warning
      std::FILE *volatile nfile = file?file:cimg::fopen(nfilename,"rb");
#else
      const char *nfilename = filename;
      std::FILE *nfile = file?file:cimg::fopen(nfilename,"rb");
#endif
      unsigned char pngCheck[8] = {};
      cimg::fread(pngCheck,8,(std::FILE*)nfile);
      if (png_sig_cmp(pngCheck,0,8)) {
        if (!file) cimg::fclose(nfile);
        throw CImgIOException(_cimg_instance

View on GitHub (pinned to f788b534b4)

Solutions

  1. Rebuild with cimg_use_png defined and link against libpng (e.g. add -Dcimg_use_png -lpng).
  2. Until rebuilt, call load_png(filename) instead of load_png(FILE*) so the generic fallback path is used.
  3. Verify the preprocessor define reaches the TU that includes CImg.h (check build flags / jni config).

Example fix

// build: LOCAL_CFLAGS += -Dcimg_use_png ; LOCAL_LDLIBS += -lpng
// before
img.load_png(file); // throws without libpng
// after
img.load_png("/path/to/image.png");
Defensive patterns

Strategy: fallback

Validate before calling

#ifdef cimg_use_png
  img.load_png(file);
#else
  img.load_png(filename); // stream loading unsupported
#endif

Try / catch

try { img.load_png(file); }
catch (CImgIOException &e) { img.load_png(filename.c_str()); }

Prevention

When it happens

Trigger: Building CImg without -Dcimg_use_png (libpng not linked) and calling load_png(std::FILE*) or load_png(istream) with a file handle but no filename.

Common situations: Android/JNI builds (like this ucrop NDK build) that omitted the libpng define in Android.mk/CMakeLists; switching code from filename-based loading to stream-based loading on a build that never had libpng enabled.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


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