Yalantis/uCrop · error · CImgIOException

save_jxl(): Failed to set basic info when saving file '%s'.

Error message

save_jxl(): Failed to set basic info when saving file '%s'.

What it means

CImg calls JxlEncoderSetBasicInfo to describe dimensions, bit depth, and channel layout to libjxl. When that call does not return JXL_ENC_SUCCESS, save_jxl() closes the file, destroys the encoder, and throws CImgIOException — the image data itself was fine, but the encoder rejected the basic info (inconsistent dimensions/BitDepth/extra-channel setup).

Source

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

        0,
      };
      JxlBasicInfo basicInfo;
      JxlEncoderInitBasicInfo(&basicInfo);
      basicInfo.bits_per_sample = bytesPerPixel*8;
      basicInfo.exponent_bits_per_sample = 0;
      basicInfo.xsize = _width;
      basicInfo.ysize = _height;
      basicInfo.uses_original_profile = JXL_FALSE;
      if (hasAlpha) {
        basicInfo.alpha_bits = bytesPerPixel*8;
        basicInfo.alpha_exponent_bits = 0;
        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);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check image width/height are > 0 before saving; JXL rejects zero or absurd dimensions.
  2. Update/align the libjxl version with the CImg.h expectations (rebuild with a current libjxl).
  3. Reduce unusual configurations: standard 8/16-bit gray or RGBA images encode reliably; verify alpha settings match _spectrum==4.

Example fix

// before
if (img.width() == 0 || img.height() == 0) {} // unchecked
img.save_jxl("out.jxl");
// after
if (img.width() == 0 || img.height() == 0) throw std::invalid_argument("empty image");
img.save_jxl("out.jxl");
Defensive patterns

Strategy: validation

Validate before calling

if (img.width() == 0 || img.height() == 0) {
  throw std::invalid_argument("image dimensions must be positive for jxl");
}
img.save_jxl("out.jxl");

Try / catch

try {
  img.save_jxl("out.jxl");
} catch (const cimg_library::CImgIOException &e) {
  std::fprintf(stderr, "jxl encoder setup failed: %s\n", e.what());
}

Prevention

When it happens

Trigger: Calling save_jxl() where the assembled JxlBasicInfo conflicts with the pixel format — e.g. mismatched exponent/sample bits for the chosen bytes_per_pixel, invalid dimensions (0 or too large), or inconsistent num_color_channels / num_extra_channels for the spectrum.

Common situations: Custom or mismatched libjxl versions where struct fields (e.g. alpha_bits, num_extra_channels) are set inconsistently; images with degenerate dimensions; ABI drift between CImg.h and an older/newer libjxl.

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


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