Yalantis/uCrop · error · CImgIOException

save_pandore(): Unsupported datatype for file '%s'.

Error message

save_pandore(): Unsupported datatype for file '%s'.

What it means

save_pandore() dispatches dimension-count writing through a macro that stores the dims array using whichever 4-byte unsigned type the platform provides (unsigned int, then unsigned short as fallback). The 'Unsupported datatype' thrown here fires when the platform has no 4-byte unsigned integer type at all — an essentially impossible configuration on modern machines, meaning this specific instance indicates an exotic platform/ABI or a misconfigured cross-build. The message names the target file (or '(FILE*)' when streaming).

Source

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

       cimg::fwrite(buffer,size(),nfile); \
       delete[] buffer

#define _cimg_save_pandore_case(sy,sz,sv,stype,id) \
      if (!saved && (sy?(sy==_height):true) && (sz?(sz==_depth):true) && \
          (sv?(sv==_spectrum):true) && !std::strcmp(stype,pixel_type())) { \
        unsigned int *iheader = (unsigned int*)(header + 12); \
        nbdims = _save_pandore_header_length((*iheader=id),dims,colorspace); \
        cimg::fwrite(header,36,nfile); \
        if (sizeof(unsigned long)==4) { CImg<ulongT> ndims(5); \
          for (int d = 0; d<5; ++d) ndims[d] = (unsigned long)dims[d]; \
          cimg::fwrite(ndims._data,nbdims,nfile); } \
        else if (sizeof(unsigned int)==4) { CImg<uintT> ndims(5); \
          for (int d = 0; d<5; ++d) ndims[d] = (unsigned int)dims[d]; \
          cimg::fwrite(ndims._data,nbdims,nfile); } \
        else if (sizeof(unsigned short)==4) { CImg<ushortT> ndims(5); \
          for (int d = 0; d<5; ++d) ndims[d] = (unsigned short)dims[d]; \
          cimg::fwrite(ndims._data,nbdims,nfile); } \
        else throw CImgIOException(_cimg_instance \
                                   "save_pandore(): Unsupported datatype for file '%s'.",\
                                   cimg_instance, \
                                   filename?filename:"(FILE*)"); \
        if (id==2 || id==5 || id==8 || id==16 || id==19 || id==22 || id==26 || id==30) { \
          __cimg_save_pandore_case(unsigned char); \
        } else if (id==3 || id==6 || id==9 || id==17 || id==20 || id==23 || id==27 || id==31) { \
          if (sizeof(unsigned long)==4) { __cimg_save_pandore_case(unsigned long); } \
          else if (sizeof(unsigned int)==4) { __cimg_save_pandore_case(unsigned int); } \
          else if (sizeof(unsigned short)==4) { __cimg_save_pandore_case(unsigned short); } \
          else throw CImgIOException(_cimg_instance \
                                     "save_pandore(): Unsupported datatype for file '%s'.",\
                                     cimg_instance, \
                                     filename?filename:"(FILE*)"); \
        } else if (id==4 || id==7 || id==10 || id==18 || id==21 || id==25 || id==29 || id==33) { \
          if (sizeof(double)==4) { __cimg_save_pandore_case(double); } \
          else if (sizeof(float)==4) { __cimg_save_pandore_case(float); } \
          else throw CImgIOException(_cimg_instance \
                                     "save_pandore(): Unsupported datatype for file '%s'.",\

View on GitHub (pinned to f788b534b4)

Solutions

  1. Target a platform/ABI where unsigned int is 4 bytes (ILP32, LP64, LLP64) — virtually all mainstream compilers.
  2. Fix the cross-compilation flags/toolchain so the standard 32-bit int model is used.
  3. Patch the CImg macro to add a fallback case (e.g. uint32_t via <cstdint>) for the offending platform.
  4. Verify sizeof(unsigned int) and sizeof(unsigned short) at configure time and fail the build early if neither is 4.

Example fix

// before
// exotic target: sizeof(unsigned int)==8, sizeof(unsigned short)==2
img.save_pandore("out.pan"); // throws on dims write

// after
#include <cstdint>
static_assert(sizeof(std::uint32_t)==4, "PANDORE writer needs 32-bit uint");
img.save_pandore("out.pan");
Defensive patterns

Strategy: validation

Validate before calling

#include <cstdint>
#if !(UINT_MAX == 4294967295u || USHRT_MAX == 65535u) /* placeholder */
// simpler:
static_assert(sizeof(unsigned int)==4 || sizeof(unsigned short)==4,
              "PANDORE writer requires a 4-byte unsigned type");

Type guard

constexpr bool pandore_dims_ok =
  sizeof(unsigned int)==4 || sizeof(unsigned short)==4;

Try / catch

try {
  img.save_pandore("out.pan");
} catch (const CImgIOException& e) {
  std::fprintf(stderr, "PANDORE unsupported on this platform ABI: %s\n", e.what());
}

Prevention

When it happens

Trigger: Saving a PANDORE file (id in the set selecting the dims-writing branch) on a platform where sizeof(unsigned int)!=4 and sizeof(unsigned short)!=4 — e.g. unusual DSP/embedded targets where unsigned short is 2 bytes and unsigned int is 8.

Common situations: Cross-compiling CImg for embedded/DSP toolchains with non-ILP32/LLP64 type widths; exotic ABIs where int is not 32-bit; static analysis flags rather than real user hits on mainstream platforms.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


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