Yalantis/uCrop · error · CImgIOException
load_jxl(): Failed to decode image data
Error message
load_jxl(): Failed to decode image data '%s'.
What it means
On JXL_DEC_NEED_IMAGE_OUT_BUFFER, load_jxl() asks libjxl for the required output size via JxlDecoderImageOutBufferSize. A non-success return makes allocating the output impossible, so the decoder is destroyed and this error is thrown. Usually reflects an unsupported pixel format choice or decoder state problem.
Solutions
- Check the image's bits_per_sample/num_color_channels; re-encode to standard 8/16-bit RGB(A) JXL.
- Update CImg/libjxl; newer libjxl accepts more format combinations.
- Decode with libjxl directly choosing a supported JxlPixelFormat, then wrap the buffer in a CImg.
Example fix
// before
// 16-bit float CMYK jxl -> ImageOutBufferSize fails
// after
// re-encode: cjxl input.png -- BitsPerSample=8 out.jxl
img.load_jxl("out.jxl"); Defensive patterns
Strategy: validation
Validate before calling
bool jxlFormatSupported(unsigned bits_per_sample, unsigned num_color_channels, unsigned alpha_bits) {
unsigned n = num_color_channels + (alpha_bits ? 1 : 0);
return (bits_per_sample == 8 || bits_per_sample == 16) && n >= 1 && n <= 4;
} Try / catch
try { img.load_jxl(path); } catch (CImgIOException& e) { log("unsupported jxl pixel format"); reencodeToStdJxl(path); } Prevention
- Normalize assets to 8/16-bit RGB(A) JXL before ingestion
- Reject CMYK/float/exotic-channel images at import
- Keep CImg and libjxl updated for broader format support
When it happens
Trigger: JxlDecoderImageOutBufferSize(decoder, &format, &imgDataSize) returns != JXL_DEC_SUCCESS where format.num_channels was set from image basic info and data_type is UINT8/UINT16 by bits_per_sample.
Common situations: Images with unusual sample layouts (e.g. >4 channels, CMYK, float samples, 32-bit depth) that clash with the hardcoded UINT8/UINT16 format choices in CImg.
Understand the failure class
- 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
- load_jxl(): Failed to set decode buffer
- load_jxl(): Does not support animated JPEG XL
- load_jxl(): Failed to configure decoder
- load_jxl(): Failed to get file size
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/4269231ac337f32d.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:57207
nfilename);
}
if (jxlInfo.have_animation!=0) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Does not support animated JPEG XL '%s'.",
cimg_instance,
nfilename);
}
hasAlpha = jxlInfo.alpha_bits!=0;
nChannels = hasAlpha?jxlInfo.num_color_channels + 1:jxlInfo.num_color_channels;
isGray = jxlInfo.num_color_channels==1;
} else if (status==JXL_DEC_NEED_IMAGE_OUT_BUFFER) {
std::size_t imgDataSize = 0;
format.num_channels = nChannels;
format.data_type = jxlInfo.bits_per_sample==16?JXL_TYPE_UINT16:JXL_TYPE_UINT8;
if (JXL_DEC_SUCCESS!=JxlDecoderImageOutBufferSize(decoder,&format,&imgDataSize)) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Failed to decode image data '%s'.",
cimg_instance,
nfilename);
}
imgData.assign(imgDataSize);
if (JXL_DEC_SUCCESS!=JxlDecoderSetImageOutBuffer(decoder,&format,(void*)imgData.data(),imgDataSize)) {
JxlDecoderDestroy(decoder);
throw CImgIOException(_cimg_instance
"load_jxl(): Failed to set decode buffer '%s'.",
cimg_instance,
nfilename);
}
}
}
assign(jxlInfo.xsize,jxlInfo.ysize,1,nChannels);
T
*ptr_r = data(0,0,0,0),View on GitHub (pinned to f788b534b4)