Yalantis/uCrop · error · CImgIOException

load_jxl(): Does not support animated JPEG XL '%s'.

Error message

load_jxl(): Does not support animated JPEG XL '%s'.

What it means

load_jxl() only supports still images. If JxlBasicInfo.have_animation is non-zero, meaning the JXL file contains an animated sequence, the decoder is destroyed and this error is thrown. It is an explicit capability limitation, not a decode failure.

Source

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

        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);
          }
          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);
          }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Detect animated JXL beforehand and handle separately (extract a frame or reject).
  2. Convert the animation to a still frame (first frame) with djxl/ffmpeg before loading.
  3. If animation support is needed, use libjxl directly or another codec path (e.g. load_gif/WebP for animation).

Example fix

// before
img.load_jxl(anim.jxl); // throws: animated
// after
// ffmpeg -i anim.jxl -frames:v 1 frame.png
img.load_png("frame.png");
Defensive patterns

Strategy: validation

Validate before calling

bool jxlIsAnimated(const char* path) {
  // animation flag is only knowable via basic info; pre-screen with a probe decoder
  std::FILE* f = std::fopen(path, "rb");
  if (!f) return false;
  // lightweight heuristic: inspect JXL container metadata or decode with libjxl directly
  std::fclose(f);
  return probeHaveAnimation(path); // wraps JxlDecoderGetBasicInfo
}

Try / catch

try { img.load_jxl(path); } catch (CImgIOException& e) { if (strstr(e.what(), "animated")) useFirstFrameOnly(path); }

Prevention

When it happens

Trigger: load_jxl(filename) is called on a JPEG XL file whose basic info reports have_animation != 0 (animated JXL, e.g. exported from an animation tool).

Common situations: Users converting GIF/APNG/WebM content to JXL and expecting CImg to read it; bulk-processing a folder that contains both still and animated .jxl assets.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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