Yalantis/uCrop · error · CImgIOException

load_jxl(): Failed to get file size '%s'.

Error message

load_jxl(): Failed to get file size '%s'.

What it means

CImg's load_jxl() first opens the file and calls cimg::fsize() to determine the JPEG XL data size; a non-positive result makes further reading impossible. The library deliberately aborts the load instead of attempting a blind decode. It indicates the file could not be sized (missing, unreadable, or special/empty file).

Source

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

    CImg<T>& _load_jxl(std::FILE *const file, const char *const filename) {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "load_jxl(): Specified filename is (null).",
                                    cimg_instance);

#ifndef cimg_use_jxl
      if (file)
        throw CImgIOException(_cimg_instance
                              "load_jxl(): Unable to load data from '(FILE*)' unless libjxl is enabled.",
                              cimg_instance);
      else return load_other(filename);
#else
      const char *nfilename = filename;
      std::FILE *nfile = file?file:cimg::fopen(nfilename,"rb");
      const long dataSize = cimg::fsize(nfile);
      if (dataSize<=0) {
        cimg::fclose(nfile);
        throw CImgIOException(_cimg_instance
                              "load_jxl(): Failed to get file size '%s'.",
                              cimg_instance,
                              nfilename);
      }
      CImg<ucharT> buffer(dataSize);
      cimg::fread(buffer._data,buffer._width,nfile);
      cimg::fclose(nfile);

      bool hasAlpha = false, isGray = false;
      uint32_t nChannels = 0;
      JxlBasicInfo jxlInfo;
      JxlPixelFormat format = { 1,JXL_TYPE_UINT8,cimg::endianness()?JXL_BIG_ENDIAN:JXL_LITTLE_ENDIAN,0 };
      CImg<ucharT> imgData;
      JxlDecoder *decoder = JxlDecoderCreate(NULL);
      if (JXL_DEC_SUCCESS!=JxlDecoderSubscribeEvents(decoder,JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE)) {
        JxlDecoderDestroy(decoder);
        throw CImgIOException(_cimg_instance
                              "load_jxl(): Failed to configure decoder '%s'.",

View on GitHub (pinned to f788b534b4)

Solutions

  1. Verify the file exists, is non-empty, and is readable before calling load_jxl() (e.g. check with stat/access).
  2. Correct the filename/path; on Android confirm the path is in app-accessible storage and the asset was actually extracted to disk.
  3. If loading from memory, use load_jxl(buffer, size) style overloads or wrap the data in a real file instead of a pipe/unseekable stream.

Example fix

// before
img.load_jxl(path); // throws if path missing/empty
// after
std::FILE* f = std::fopen(path, "rb");
if (!f || cimg::fsize(f) <= 0) { /* handle invalid file */ }
else { std::fclose(f); img.load_jxl(path); }
Defensive patterns

Strategy: validation

Validate before calling

bool canLoadJxl(const char* path) {
  if (!path) return false;
  std::FILE* f = std::fopen(path, "rb");
  if (!f) return false;
  long sz = cimg::fsize(f);
  std::fclose(f);
  return sz > 0;
}

Try / catch

try { img.load_jxl(path); } catch (CImgIOException& e) { log << "unreadable jxl: " << e.what(); usePlaceholder(); }

Prevention

When it happens

Trigger: CImg<T>::load_jxl(filename) is called and cimg::fsize() returns <= 0: the path does not exist, points to an empty file, or the FILE* cannot be stat'd/fseek'd to the end.

Common situations: Passing a wrong or typo'd path, a zero-byte .jxl file, a directory instead of a file, or a file stream that is already at EOF/unreadable due to permissions on Android NDK (ucrop JNI context).

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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