Yalantis/uCrop · error · CImgIOException

load_jpeg(): Unable to load data from '(FILE*)' unless libjp

Error message

load_jpeg(): Unable to load data from '(FILE*)' unless libjpeg is enabled.

What it means

When CImg is compiled without libjpeg support (cimg_use_jpeg not defined), JPEG decoding from an already-open FILE* is impossible because the fallback path needs a filename to dispatch to another loader. CImg throws CImgIOException explaining that libjpeg must be enabled.

Source

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

    typedef struct _cimg_error_mgr *_cimg_error_ptr;

    METHODDEF(void) _cimg_jpeg_error_exit(j_common_ptr cinfo) {
      _cimg_error_ptr c_err = (_cimg_error_ptr) cinfo->err; // Return control to the setjmp point
      (*cinfo->err->format_message)(cinfo,c_err->message);
      jpeg_destroy(cinfo); // Clean memory and temp files
      longjmp(c_err->setjmp_buffer,1);
    }
#endif

    CImg<T>& _load_jpeg(std::FILE *const file, const char *const filename) {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "load_jpeg(): Specified filename is (null).",
                                    cimg_instance);

#ifndef cimg_use_jpeg
      if (file)
        throw CImgIOException(_cimg_instance
                              "load_jpeg(): Unable to load data from '(FILE*)' unless libjpeg is enabled.",
                              cimg_instance);
      else return load_other(filename);
#else

#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

      struct jpeg_decompress_struct cinfo;
      struct _cimg_error_mgr jerr;
      cinfo.err = jpeg_std_error(&jerr.original);
      jerr.original.error_exit = _cimg_jpeg_error_exit;
      if (setjmp(jerr.setjmp_buffer)) { // JPEG error

View on GitHub (pinned to f788b534b4)

Solutions

  1. Rebuild with libjpeg enabled (define cimg_use_jpeg and link libjpeg/libjpeg-turbo)
  2. Install libjpeg development headers (e.g. apt install libjpeg-dev) and recompile
  3. Pass a filesystem path instead of a FILE* so CImg can delegate to another loader
  4. Use a different image format (PNG) supported by the current build

Example fix

// build: -Dcimg_use_jpeg=1 -ljpeg
// before
img.load_jpeg(assetFile); // FILE*, build lacks libjpeg
// after
// rebuild with libjpeg, or:
img.load_jpeg("/path/to/image.jpg");
Defensive patterns

Strategy: fallback

Validate before calling

#ifndef cimg_use_jpeg
  #error "Rebuild with cimg_use_jpeg for FILE*-based JPEG loading"
#endif

Type guard

bool canLoadJpegFromFilePtr() {
#ifdef cimg_use_jpeg
  return true;
#else
  return false;
#endif
}

Try / catch

try { img.load_jpeg(file, filename); }
catch (CImgIOException&) { img.load_jpeg("/sdcard/extracted.jpg"); // path fallback
}

Prevention

When it happens

Trigger: Calling load_jpeg(std::FILE*) on a build where cimg_use_jpeg is not defined; in-memory streams/asset FILE* in an Android/uCrop JNI build lacking libjpeg.

Common situations: Build configured without cimg_use_jpeg (no cimg_jpeg flags / libjpeg-dev missing), while the app hands CImg a FILE* from Android assets.

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/59ac7eb9eb7dc67c. Report an issue: GitHub.