Yalantis/uCrop · warning

save_jxl(): Instance is volumetric, only the first slice wil

Error message

save_jxl(): Instance is volumetric, only the first slice will be saved in file '%s'.

What it means

Warning emitted by CImg<T>::save_jxl() when the image has depth > 1 (a volumetric image, i.e. a 3D stack). JPEG XL stores single 2D images, so only the first slice (z=0) is written to the file and all other slices are silently dropped. The save itself succeeds.

Source

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

        throw CImgArgumentException(_cimg_instance
                                    "save_jxl(): Specified filename is (null).",
                                    cimg_instance);
      if (_spectrum > 4)
        throw CImgArgumentException(_cimg_instance
                                    "save_jxl(): JPEG XL only supports at most 4 channels.",
                                    cimg_instance);
      double stmin, stmax = (double)max_min(stmin);
      if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)
        cimg::warn(_cimg_instance
                   "save_jxl(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.",
                   cimg_instance,
                   stmin,stmax,filename);
      if (bytes_per_pixel>2 || sizeof(T)<bytes_per_pixel)
        throw CImgArgumentException(_cimg_instance
                                    "save_jxl(): bytes_per_pixel must be in [0, 2] and less than or equal to sizeof(T)",
                                    cimg_instance);
      if (_depth>1)
        cimg::warn(_cimg_instance
                   "save_jxl(): Instance is volumetric, only the first slice will be saved in file '%s'.",
                   cimg_instance,
                   filename);
#ifndef cimg_use_jxl
      cimg::unused(distance);
      return save_other(filename);
#else
      std::FILE *file = cimg::fopen(filename, "wb");
      cimg_uint32 nChannels = _spectrum;
      bool hasAlpha = _spectrum==2 || _spectrum==4;
      if (hasAlpha) --nChannels;
      unsigned int bytesPerPixel = bytes_per_pixel;
      if (bytesPerPixel==0)
          bytesPerPixel = stmax<256?1:2;
      CImg<ucharT> rgbBuffer(_width*_height*nChannels*bytesPerPixel);
      const T *ptr_r = 0, *ptr_g = 0, *ptr_b = 0, *ptr_a = 0;
      switch (_spectrum) {
      case 1:

View on GitHub (pinned to f788b534b4)

Solutions

  1. Save each slice separately: cimg_for_z(img,z) img.get_slice(z).save_jxl(...);
  2. Use a volume-capable format (TIFF, NIfTI, .cimg) instead
  3. Flatten or project the volume if a single 2D result is intended
  4. Ignore if only the first slice is wanted

Example fix

// before
volume.save_jxl("out.jxl"); // only slice 0 saved
// after
cimg_for_z(volume,z) volume.get_slice(z).save_jxl(cimg::format("out_%d.jxl",z));
Defensive patterns

Strategy: validation

Validate before calling

if (img.depth() > 1) { /* save slices or choose another format */ }

Try / catch

// warning only; guard by depth check before calling save_jxl

Prevention

When it happens

Trigger: Calling save_jxl() on a CImg whose _depth>1, e.g. after get_slice() misuse, loading a multi-page/multi-frame volume, or constructing an image with depth dimension greater than 1.

Common situations: Saving medical imaging volumes (MRI/CT stacks), video frames stored as depth, or z-stacks loaded from TIFF/NIfTI directly to JPEG XL.

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/2a8934b0a1ef3c93. Report an issue: GitHub.