Yalantis/uCrop · error · CImgIOException

load_jxl(): Failed to set decode buffer '%s'.

Error message

load_jxl(): Failed to set decode buffer '%s'.

What it means

After allocating imgData, load_jxl() hands the buffer to libjxl with JxlDecoderSetImageOutBuffer. A non-success return means libjxl refused the output buffer, so the decoder is destroyed and this error is thrown. Typically a size/format mismatch between the allocated buffer and what the decoder requires.

Source

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

          }
          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),
        *ptr_g = isGray?0:data(0,0,0,1),
        *ptr_b = isGray?0:data(0,0,0,2),
        *ptr_a = !hasAlpha?0:data(0,0,0,isGray?1:3);
      switch (jxlInfo.bits_per_sample) {
      case 8: {
        cimg_forY(*this,y) {
          const uint8_t *ptrs = (uint8_t*)&imgData[y*_width*_spectrum*sizeof(uint8_t)];
          cimg_forX(*this,x) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Rebuild JNI code against the deployed libjxl version so JxlPixelFormat and size semantics match.
  2. Confirm imgData.assign(imgDataSize) succeeded (buffer.data() non-null, correct size).
  3. Upgrade CImg; check known libjxl issues around SetImageOutBuffer for your version.

Example fix

// before
imgData.assign(imgDataSize); // OOM -> null/short buffer
JxlDecoderSetImageOutBuffer(...); // fails
// after
imgData.assign(imgDataSize);
if (imgData.size() != imgDataSize) { /* handle alloc failure */ }
JxlDecoderSetImageOutBuffer(dec, &format, imgData.data(), imgDataSize);
Defensive patterns

Strategy: try-catch

Try / catch

try { img.load_jxl(path); } catch (CImgIOException& e) { if (strstr(e.what(), "decode buffer")) reportAllocationOrAbiIssue(e); }

Prevention

When it happens

Trigger: JxlDecoderSetImageOutBuffer(decoder, &format, imgData.data(), imgDataSize) returns != JXL_DEC_SUCCESS during load_jxl()'s NEED_IMAGE_OUT_BUFFER handling.

Common situations: imgDataSize from JxlDecoderImageOutBufferSize not matching the assigned buffer (allocation failure of imgData.assign), or format struct mutated between the two calls (ABI mismatch across libjxl versions).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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