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
- Target a platform/ABI where unsigned int is 4 bytes (ILP32, LP64, LLP64) — virtually all mainstream compilers.
- Fix the cross-compilation flags/toolchain so the standard 32-bit int model is used.
- Patch the CImg macro to add a fallback case (e.g. uint32_t via <cstdint>) for the offending platform.
- 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
- static_assert type widths at build time for cross-compiled targets
- Avoid nonstandard -fshort-enums / int-width-changing flags
- Test savers on each embedded target ABI you ship
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
- load_pandore(): File size %lu for filename '%s' does not mat
- load_pandore(): Unknown pixel datatype in file '%s'.
- load_pandore(): Specified filename is (null).
- load_pandore(): PANDORE header not found in file '%s'.
- load_pandore(): Unable to load data with ID_type %u in file
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/9cb3e2c1c607e6c9.
Report an issue: GitHub.