Yalantis/uCrop · error · CImgIOException

load_jpeg(): Error message returned by libjpeg: %s.

Error message

load_jpeg(): Error message returned by libjpeg: %s.

What it means

CImg installs a custom libjpeg error handler; when libjpeg signals any decode error (corrupt data, unsupported marker, premature EOF) the handler longjmps back and CImg throws CImgIOException containing libjpeg's own message string.

Source

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

                              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
        if (!file) cimg::fclose(nfile);
        throw CImgIOException(_cimg_instance
                             "load_jpeg(): Error message returned by libjpeg: %s.",
                             cimg_instance,jerr.message);
      }

      jpeg_create_decompress(&cinfo);
      jpeg_stdio_src(&cinfo,nfile);
      jpeg_read_header(&cinfo,TRUE);
      jpeg_start_decompress(&cinfo);

      if (cinfo.output_components!=1 && cinfo.output_components!=3 && cinfo.output_components!=4) {
        if (!file) {
          cimg::fclose(nfile);
          return load_other(nfilename);
        } else
          throw CImgIOException(_cimg_instance
                                "load_jpeg(): Failed to load JPEG data from file '%s'.",
                                cimg_instance,nfilename?nfilename:"(FILE*)");
      }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Verify/repair the file (e.g. jpegtran -copy none, or re-save in an image editor)
  2. Re-download or re-export the JPEG
  3. Read jerr.message in the exception text to identify the specific libjpeg failure
  4. Fallback-decode with another library (e.g. stb_image, libvips) or convert the file to PNG

Example fix

// before
img.load_jpeg("broken.jpg"); // throws on corrupt data
// after
try { img.load_jpeg("broken.jpg"); }
catch (CImgIOException& e) {
  // e includes libjpeg's message; attempt fallback
  img.load("broken_reexported.png");
}
Defensive patterns

Strategy: try-catch

Validate before calling

unsigned char soi[2]; FILE* f=fopen(path,"rb");
bool isJpeg = f && fread(soi,1,2,f)==2 && soi[0]==0xFF && soi[1]==0xD8;
if (f) fclose(f);
if (!isJpeg) throw std::runtime_error("not a jpeg");

Try / catch

try { img.load_jpeg(path); }
catch (CImgIOException& e) {
  // e.what() contains libjpeg's message for diagnostics
  img.assign(); // or fallback decode
}

Prevention

When it happens

Trigger: load_jpeg on a truncated or corrupted JPEG; unsupported JPEG variants (e.g. arithmetic coding, progressive with broken scans); wrong format with .jpg extension.

Common situations: Incomplete uploads/downloads, resumptions from partially cached assets, images processed by lossy tools, rare JPEG chroma subsampling combinations.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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