Yalantis/uCrop · error · CImgInstanceException

save_tiff(): Unsupported pixel type '%s' for file '%s'.

Error message

save_tiff(): Unsupported pixel type '%s' for file '%s'.

What it means

CImg's save_tiff() only supports a fixed set of pixel types (int32, uint64-as-int32, int64-as-int32, float32, float64-as-float32) when writing via libtiff. When the image instance's pixel type T does not map to any registered writer case, the dispatcher falls through and throws CImgInstanceException naming the actual pixel_type() and the TIFF file name. Note that per the source, 64-bit types are silently downcast, so the error is only about truly unmatched types (e.g. unsigned char/short or float16-style data).

Source

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

      TIFFWriteDirectory(tif);
      return *this;
    }

    const CImg<T>& _save_tiff(TIFF *tif, const unsigned int directory, const unsigned int z,
                              const unsigned int compression_type, const float *const voxel_size,
                              const char *const description, double val_min, double val_max) const {
      _cimg_save_tiff("uint8",cimg_uint8);
      _cimg_save_tiff("int8",cimg_int8);
      _cimg_save_tiff("uint16",cimg_uint16);
      _cimg_save_tiff("int16",cimg_int16);
      _cimg_save_tiff("uint32",cimg_uint32);
      _cimg_save_tiff("int32",cimg_int32);
      _cimg_save_tiff("uint64",cimg_uint32); // 'int64' as 'int32'
      _cimg_save_tiff("int64",cimg_int32);
      _cimg_save_tiff("float32",cimg_float32);
      _cimg_save_tiff("float64",cimg_float32); // 'float64' as 'float32'
      const char *const filename = TIFFFileName(tif);
      throw CImgInstanceException(_cimg_instance
                                  "save_tiff(): Unsupported pixel type '%s' for file '%s'.",
                                  cimg_instance,
                                  pixel_type(),filename?filename:"(FILE*)");
      return *this;
    }
#endif

    //! Save image as a MINC2 file.
    /**
       \param filename Filename, as a C-string.
       \param imitate_file If non-zero, reference filename, as a C-string, to borrow header from.
    **/
    const CImg<T>& save_minc2(const char *const filename,
                              const char *const imitate_file=0) const {
      if (!filename)
        throw CImgArgumentException(_cimg_instance
                                   "save_minc2(): Specified filename is (null).",
                                   cimg_instance);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Convert the image to a supported type before saving: img.get_float32().save_tiff(filename) or get_save via .get_resize of type, e.g. CImg<float>(img).save_tiff(filename).
  2. If 8-bit data must stay 8-bit, use a different format that supports it (save_png, save_bmp) or the cimg_use_tiff build with a matching case.
  3. Check the CImg version; newer versions register more pixel type cases for TIFF — updating CImg.h may remove the error.
  4. Specialize the save call on pixel type explicitly instead of calling save() generically, so unsupported types are rejected early with a clear message.

Example fix

// before
CImg<unsigned char> mask(512,512,1,3,0);
mask.save_tiff("out.tif"); // throws: unsupported pixel type 'unsigned char'

// after
CImg<float> maskf(mask);
maskf.save_tiff("out.tif");
Defensive patterns

Strategy: validation

Validate before calling

static const char* kTiffTypes[] = {"int32","uint32","int64","uint64","float32","float64"};
bool ok = false;
for (const char* t : kTiffTypes)
  if (!cimg::strcasecmp(img.pixel_type(), t)) { ok = true; break; }
if (!ok) throw std::runtime_error(std::string("TIFF unsupported for ") + img.pixel_type());

Type guard

template <typename T>
constexpr bool tiff_supported() {
  return std::is_same_v<T,cimg_int32> || std::is_same_v<T,cimg_uint32>
      || std::is_same_v<T,float> || std::is_same_v<T,double>;
}

Try / catch

try {
  img.save_tiff("out.tif");
} catch (const CImgInstanceException& e) {
  std::fprintf(stderr, "TIFF save failed (%s); converting to float\n", e.what());
  CImg<float>(img).save_tiff("out.tif");
}

Prevention

When it happens

Trigger: Calling CImg<T>::save_tiff() (directly or via save()) with a CImg instantiated on an unsupported element type such as CImg<unsigned char>, CImg<unsigned short>, or CImg<bool>, since the TIFF writer has no _cimg_save_tiff case for those widths.

Common situations: Saving grayscale masks or edge maps built as unsigned char/short images to .tif/.tiff; code written for a float pipeline later reused with 8-bit images; pixel type changed during a refactor while the save call stayed generic through save(filename).

Related errors


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