{"record":{"id":"00c6f90fda63131d","repo":"Yalantis/uCrop","slug":"save-jxl-jpeg-xl-only-supports-at-most-4-channe","errorCode":null,"errorMessage":"save_jxl(): JPEG XL only supports at most 4 channels.","messagePattern":"save_jxl\\(\\): JPEG XL only supports at most 4 channels\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":61770,"sourceCode":"    /**\n      \\param filename Filename, as a C-string.\n      \\param distance Sets the level for lossy compression: lower = higher quality.\n        Range: 0 .. 25. 0.0 = mathematically lossless\n      \\param bytes_per_pixel Force the number of bytes per pixels for the saving, when possible.\n    **/\n    const CImg<T>& save_jxl(const char *const filename, const float distance=1.0f,\n                            const unsigned int bytes_per_pixel=0) const {\n      return _save_jxl(filename,distance,bytes_per_pixel);\n    }\n\n    const CImg<T>& _save_jxl(const char *const filename, const float distance=1.0f,\n                             const unsigned int bytes_per_pixel=0) const {\n      if (!filename)\n        throw CImgArgumentException(_cimg_instance\n                                    \"save_jxl(): Specified filename is (null).\",\n                                    cimg_instance);\n      if (_spectrum > 4)\n        throw CImgArgumentException(_cimg_instance\n                                    \"save_jxl(): JPEG XL only supports at most 4 channels.\",\n                                    cimg_instance);\n      double stmin, stmax = (double)max_min(stmin);\n      if (stmin<0 || (bytes_per_pixel==1 && stmax>=256) || stmax>=65536)\n        cimg::warn(_cimg_instance\n                   \"save_jxl(): Instance has pixel values in [%g,%g], probable type overflow in file '%s'.\",\n                   cimg_instance,\n                   stmin,stmax,filename);\n      if (bytes_per_pixel>2 || sizeof(T)<bytes_per_pixel)\n        throw CImgArgumentException(_cimg_instance\n                                    \"save_jxl(): bytes_per_pixel must be in [0, 2] and less than or equal to sizeof(T)\",\n                                    cimg_instance);\n      if (_depth>1)\n        cimg::warn(_cimg_instance\n                   \"save_jxl(): Instance is volumetric, only the first slice will be saved in file '%s'.\",\n                   cimg_instance,\n                   filename);\n#ifndef cimg_use_jxl","sourceCodeStart":61752,"sourceCodeEnd":61788,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L61752-L61788","documentation":"JPEG XL encoding in CImg supports at most 4 channels (gray, RGB, RGB+alpha, RGBA). save_jxl() throws CImgArgumentException when the image's _spectrum exceeds 4, before any encoder setup, because libjxl's basic info cannot represent that channel count.","triggerScenarios":"Calling save_jxl() on an image whose _spectrum > 4, e.g. multispectral/hyperspectral data, CMYK+extra channels, or images produced by concatenating many channel planes.","commonSituations":"Scientific imaging and remote-sensing pipelines where images carry 5+ spectral bands, then get saved to JXL for compression without channel reduction.","solutions":["Reduce channels before saving: img.channels(0,3) to keep the first 4, or split into multiple images.","Pack channels differently (e.g. save each band as a separate grayscale JXL file).","Choose a format that supports more channels (e.g. TIFF) instead of JXL."],"exampleFix":"// before\nimg.save_jxl(\"spectral.jxl\"); // img.spectrum() == 8\n// after\nCImg<T> vis = img.get_channels(0, 0, 0, 0, 0, 3); // keep RGB-like subset\nvis.save_jxl(\"spectral.jxl\");","handlingStrategy":"validation","validationCode":"if (img.spectrum() > 4) {\n  img.channels(0, 3); // keep first 4 channels before jxl save\n}\nimg.save_jxl(\"out.jxl\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reject or reduce >4-channel images at ingestion.","Document that JXL output supports at most 4 channels.","Route multispectral data to formats like TIFF."],"tags":["cimg","jxl","channels","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}