Yalantis/uCrop · error · CImgArgumentException
save_pandore(): Specified filename is (null).
Error message
save_pandore(): Specified filename is (null).
What it means
CImg's save_pandore() writes the image in the PANDORE file format to either a FILE* or a filename. Because it needs one of the two output targets, it throws CImgArgumentException when both are null. This is a pure caller-contract check performed before any I/O happens.
Source
Thrown at ucrop/src/main/jni/CImg.h:63285
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'.",\
cimg_instance, \
filename?filename:"(FILE*)"); \
} \
saved = true; \
}
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"save_pandore(): Specified filename is (null).",
cimg_instance);
if (is_empty()) { cimg::fempty(file,filename); return *this; }
std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
unsigned char header[36] = { 'P','A','N','D','O','R','E','0','4',0,0,0,
0,0,0,0,'C','I','m','g',0,0,0,0,0,
'N','o',' ','d','a','t','e',0,0,0,0 };
unsigned int nbdims, dims[5] = {};
bool saved = false;
_cimg_save_pandore_case(1,1,1,"uint8",2);
_cimg_save_pandore_case(1,1,1,"int8",3);
_cimg_save_pandore_case(1,1,1,"uint16",3);
_cimg_save_pandore_case(1,1,1,"int16",3);
_cimg_save_pandore_case(1,1,1,"uint32",3);
_cimg_save_pandore_case(1,1,1,"int32",3);
_cimg_save_pandore_case(1,1,1,"uint64",3);
_cimg_save_pandore_case(1,1,1,"int64",3);View on GitHub (pinned to f788b534b4)
Solutions
- Pass a valid non-null filename, e.g. img.save_pandore("out.pan").
- If writing to an already-open stream, pass the std::FILE* instead of a filename.
- Guard the path upstream: if (path && *path) img.save_pandore(path); else handle the missing path.
Example fix
// before
img.save_pandore(); // filename defaults to 0
// after
img.save_pandore("output.pan"); Defensive patterns
Strategy: validation
Validate before calling
if (!filename || !*filename) { /* choose default or abort */ filename = "output.pan"; }
img.save_pandore(filename); Type guard
bool hasOutputTarget(std::FILE *f, const char *name) { return f != nullptr || (name != nullptr && name[0] != '\0'); } Try / catch
try { img.save_pandore(path.c_str()); }
catch (cimg_library::CImgArgumentException &e) { std::fprintf(stderr, "bad save args: %s\n", e.what()); } Prevention
- Always pass std::string::c_str() of a checked, non-empty path.
- Never rely on default arguments for output filenames.
- Centralize saves in a helper that validates the path first.
When it happens
Trigger: Calling save_pandore() with no arguments (default filename is 0/null) or explicitly passing NULL as the filename while also not passing a FILE*.
Common situations: Passing a std::string's c_str() from a variable that was never set, propagating an empty/null path from upper layers, or accidentally calling the no-argument overload expecting a default file name.
Related errors
- save_raw(): Specified filename is (null).
- save_graphicsmagick_external(): Specified filename is (null)
- load_parrec(): Specified filename is (null).
- cimg::ftype(): Specified filename is (null).
- cimg::fopen(): Specified file path is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/6b00899195ccf5d0.
Report an issue: GitHub.