Yalantis/uCrop · error · CImgArgumentException

save_tiff(): Specified compression type (%u) is invalid (sho

Error message

save_tiff(): Specified compression type (%u) is invalid (should be in range [0,%u]).

What it means

In _save_tiff, the compression_type argument is used as an index into a fixed table of libtiff COMPRESSION_* codes; if the index is >= nb_compression_codes the value does not map to a known compression scheme and CImgArgumentException is thrown, reporting the valid range [0, nb-1].

Source

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

                              const char *const description, double val_min, double val_max) const {
      if (is_empty() || !tif || pixel_t) return *this;
      const unsigned int compression_codes[] = {
        COMPRESSION_NONE, COMPRESSION_ADOBE_DEFLATE, COMPRESSION_CCITT_T4, COMPRESSION_CCITT_T6,
        COMPRESSION_CCITTFAX3, COMPRESSION_CCITTFAX4, COMPRESSION_CCITTRLE, COMPRESSION_CCITTRLEW,
        COMPRESSION_DCS, COMPRESSION_DEFLATE, COMPRESSION_IT8BL, COMPRESSION_IT8CTPAD, COMPRESSION_IT8LW,
        COMPRESSION_IT8MP, COMPRESSION_JBIG, COMPRESSION_JP2000, COMPRESSION_JPEG,
#ifdef COMPRESSION_JXL
        COMPRESSION_JXL,
#else
        COMPRESSION_NONE,
#endif
        COMPRESSION_LERC, COMPRESSION_LZMA, COMPRESSION_LZW, COMPRESSION_NEXT, COMPRESSION_OJPEG,
        COMPRESSION_PACKBITS, COMPRESSION_PIXARFILM, COMPRESSION_PIXARLOG, COMPRESSION_SGILOG,
        COMPRESSION_SGILOG24, COMPRESSION_T43, COMPRESSION_T85, COMPRESSION_THUNDERSCAN, COMPRESSION_WEBP,
        COMPRESSION_ZSTD },
        nb_compression_codes = sizeof(compression_codes)/sizeof(unsigned int);
      if (compression_type>=nb_compression_codes)
        throw CImgArgumentException(_cimg_instance
                                    "save_tiff(): Specified compression type (%u) is invalid "
                                    "(should be in range [0,%u]).",
                                    cimg_instance,nb_compression_codes - 1);
      const unsigned int compression_code = compression_codes[compression_type];
      const char *const filename = TIFFFileName(tif);
      cimg_uint32 rowsperstrip = (cimg_uint32)-1;
      cimg_uint16 spp = _spectrum, bpp = sizeof(t)*8, photometric;
      if (spp==3 || spp==4) photometric = PHOTOMETRIC_RGB;
      else photometric = PHOTOMETRIC_MINISBLACK;
      TIFFSetDirectory(tif,directory);
      TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,_width);
      TIFFSetField(tif,TIFFTAG_IMAGELENGTH,_height);
      if (voxel_size) {
        const float vx = voxel_size[0], vy = voxel_size[1], vz = voxel_size[2];
        TIFFSetField(tif,TIFFTAG_RESOLUTIONUNIT,RESUNIT_NONE);
        TIFFSetField(tif,TIFFTAG_XRESOLUTION,1.f/vx);
        TIFFSetField(tif,TIFFTAG_YRESOLUTION,1.f/vy);
        CImg<charT> s_description(256);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Pass a table index within [0, nb_compression_codes-1], not a raw COMPRESSION_* constant
  2. Determine the index of the desired scheme in CImg's compression_codes array for your build
  3. Use compression_type=0 (no/none) to test, then add compression incrementally
  4. Pin libtiff version so the table size matches your chosen index

Example fix

// before
img.save_tiff("out.tif", COMPRESSION_DEFLATE); // raw constant = wrong
// after
// index of COMPRESSION_ADOBE_DEFLATE within CImg's compression_codes table
img.save_tiff("out.tif", 8);
Defensive patterns

Strategy: validation

Validate before calling

// index into CImg's compression_codes table, not a raw COMPRESSION_* constant
if (compression_type < 0 || compression_type > maxCompressionIndex()) throw std::out_of_range("bad tiff compression index");

Type guard

bool isValidCompressionIndex(unsigned t) { return t <= 30; } // keep in sync with libtiff build table size

Try / catch

try { img.save_tiff(path, compIdx); } catch (CImgArgumentException &e) { /* invalid compression */ compIdx = 0; img.save_tiff(path, compIdx); }

Prevention

When it happens

Trigger: Calling save_tiff(filename, compression_type) or _save_tiff with a numeric compression id beyond the size of CImg's table (table size varies with libtiff build/version); passing raw libtiff COMPRESSION_* constants (e.g. COMPRESSION_LZW=5) directly instead of the table index.

Common situations: Users copying libtiff constant values into CImg's index parameter; libtiff upgrade/downgrade changing the number of supported codes; hard-coded index from documentation of a different CImg/libtiff version.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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