Yalantis/uCrop · error · CImgIOException
load_jxl(): Failed to decode image '%s'.
Error message
load_jxl(): Failed to decode image '%s'.
What it means
During the JxlDecoderProcessInput loop, status JXL_DEC_ERROR or JXL_DEC_NEED_MORE_INPUT means the bitstream could not be decoded (or was incomplete), so CImg destroys the decoder and throws. This is the generic 'not valid / corrupt JPEG XL data' failure.
Source
Thrown at ucrop/src/main/jni/CImg.h:57179
"load_jxl(): Failed to configure decoder '%s'.",
cimg_instance,
nfilename);
}
if (JXL_DEC_SUCCESS!=JxlDecoderSetInput(decoder,buffer._data,buffer._width)) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Failed to load image data '%s'.",
cimg_instance,
nfilename);
}
JxlDecoderCloseInput(decoder);
while (true) {
JxlDecoderStatus status = JxlDecoderProcessInput(decoder);
if (status==JXL_DEC_SUCCESS || status==JXL_DEC_FULL_IMAGE) break;
else if (status==JXL_DEC_ERROR || status==JXL_DEC_NEED_MORE_INPUT) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Failed to decode image '%s'.",
cimg_instance,
nfilename);
} else if (status==JXL_DEC_BASIC_INFO) {
if (JXL_DEC_SUCCESS!=JxlDecoderGetBasicInfo(decoder,&jxlInfo)) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Failed to load image data '%s'.",
cimg_instance,
nfilename);
}
if (jxlInfo.have_animation!=0) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Does not support animated JPEG XL '%s'.",
cimg_instance,
nfilename);
}View on GitHub (pinned to f788b534b4)
Solutions
- Validate the file is a genuine JPEG XL image (check FF 0A signature or JXL container box) before loading.
- Re-obtain a complete, untruncated copy of the file (verify size/checksum).
- If the image may not be JXL, sniff the format first (cimg::file_type) and dispatch to the appropriate load_* function.
- For NEED_MORE_INPUT caused by non-standard containers, decode with libjxl's cjxl/djxl-compatible reference setup or convert the file.
Example fix
// before
img.load_jxl(userFile); // corrupt/renamed file throws
// after
if (cimg::file_type(userFile) != "jxl") { /* route to load_jpeg etc. */ }
else img.load_jxl(userFile); Defensive patterns
Strategy: validation
Validate before calling
bool looksLikeJxl(const unsigned char* d, size_t n) {
if (n < 2) return false;
if (d[0] == 0xFF && d[1] == 0x0A) return true; // codestream
return n >= 12 && std::memcmp(d, "\x00\x00\x00\x0CJXL ", 8) == 0; // container
} Try / catch
try { img.load_jxl(path); } catch (CImgIOException& e) { log("not valid jxl, falling back to sniffed loader"); img.load(path); } Prevention
- Sniff file signature before choosing a decoder; never trust extensions
- Reject or repair truncated files early (NEED_MORE_INPUT means incomplete)
- Keep a fallback load() path that dispatches by detected format
When it happens
Trigger: JxlDecoderProcessInput returns JXL_DEC_ERROR or JXL_DEC_NEED_MORE_INPUT inside load_jxl()'s decode loop, typically because the file is not a valid JXL codestream/container or is truncated.
Common situations: Renaming a JPEG/PNG to .jxl and feeding it to load_jxl, partially downloaded files, or ISOBMFF container with data CImg's simple single-pass loop does not supply (NEED_MORE_INPUT).
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- load_jxl(): Failed to decode image data '%s'.
- load_jxl(): Failed to set decode buffer '%s'.
- load_bmp(): Invalid offset %d specified in filename '%s'.
- load_bmp(): File size %lu for filename '%s' does not match e
- load_bmp(): Malformed header in filename '%s'.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/e1dbb46d4507f5fc.
Report an issue: GitHub.