Yalantis/uCrop · error · CImgIOException
save_jxl(): Failed to set color encoding when saving file '%
Error message
save_jxl(): Failed to set color encoding when saving file '%s'.
What it means
After setting basic info, save_jxl() configures the color encoding to sRGB (gray or color) via JxlEncoderSetColorEncoding. If libjxl returns non-success, CImg closes the file, destroys the encoder, and throws CImgIOException, because a JXL stream cannot be produced without a valid color encoding.
Source
Thrown at ucrop/src/main/jni/CImg.h:61877
basicInfo.num_extra_channels = 1;
}
basicInfo.num_color_channels = nChannels;
if (JXL_ENC_SUCCESS!=JxlEncoderSetBasicInfo(encoder,&basicInfo)) {
cimg::fclose(file);
JxlEncoderDestroy(encoder);
throw CImgIOException(_cimg_instance
"save_jxl(): Failed to set basic info when saving file '%s'.",
cimg_instance,
filename);
}
JxlColorEncoding colorEncoding = {};
JXL_BOOL isGray = pixelFormat.num_channels<3?JXL_TRUE:JXL_FALSE;
JxlColorEncodingSetToSRGB(&colorEncoding, isGray);
if (JXL_ENC_SUCCESS!=JxlEncoderSetColorEncoding(encoder,&colorEncoding)) {
cimg::fclose(file);
JxlEncoderDestroy(encoder);
throw CImgIOException(_cimg_instance
"save_jxl(): Failed to set color encoding when saving file '%s'.",
cimg_instance,
filename);
}
JxlEncoderFrameSettings* frameSettings = JxlEncoderFrameSettingsCreate(encoder,NULL);
if (JXL_ENC_SUCCESS!=JxlEncoderSetFrameDistance(frameSettings,distance)) {
cimg::fclose(file);
JxlEncoderDestroy(encoder);
throw CImgIOException(_cimg_instance
"save_jxl(): Failed to set lossy compression level when saving file '%s'.",
cimg_instance,
filename);
}
if (JXL_ENC_SUCCESS!=JxlEncoderAddImageFrame(frameSettings,&pixelFormat,(const void*)rgbBuffer._data,
rgbBuffer.size())) {
cimg::fclose(file);
JxlEncoderDestroy(encoder);View on GitHub (pinned to f788b534b4)
Solutions
- Save with a standard channel count (1 for gray, 3/4 for RGB(A)); convert the image first: img.resize(-100,-100,-100,3).
- Rebuild against a current libjxl so JxlEncoderSetColorEncoding behaves as CImg expects.
- Ensure JxlEncoderSetBasicInfo succeeded with a channel layout consistent with the pixel format (isGray flag matches num_channels<3).
Example fix
// before
img.save_jxl("out.jxl"); // img.spectrum()==2, inconsistent with gray/color setup
// after
img.resize(-100, -100, -100, 3); // normalize to RGB
img.save_jxl("out.jxl"); Defensive patterns
Strategy: try-catch
Validate before calling
if (img.spectrum() != 1 && img.spectrum() != 3 && img.spectrum() != 4) {
img.resize(-100, -100, -100, 3); // normalize so color encoding setup is consistent
} Try / catch
try {
img.save_jxl("out.jxl");
} catch (const cimg_library::CImgIOException &e) {
std::fprintf(stderr, "jxl color encoding failed: %s\n", e.what());
img.save_png("out.png");
} Prevention
- Use channel counts that map cleanly to gray or sRGB color profiles.
- Rebuild against a current libjxl.
- Normalize images to RGB before JXL saves.
When it happens
Trigger: save_jxl() on an image where the pixel format's channel count implies gray but the encoder state disagrees (or vice versa), or a libjxl build/state where the color-encoding step fails after basic info was accepted.
Common situations: Mismatch between basic info (set earlier) and pixelFormat.num_channels — e.g. custom channel layouts; incompatible or very old libjxl versions lacking API/behaviour expected by CImg.h.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- load_jxl(): Failed to configure decoder '%s'.
- save_jxl(): Failed to set basic info when saving file '%s'.
- load_jxl(): Unable to load data from '(FILE*)' unless libjxl
- load_jxl(): Failed to get file size '%s'.
- load_jxl(): Failed to load image data '%s'.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/fec06d289e3851ac.
Report an issue: GitHub.