Yalantis/uCrop · error · CImgArgumentException
save_pnk(): Specified filename is (null).
Error message
save_pnk(): Specified filename is (null).
What it means
save_pnk() (Portable Anymap single-channel writer) throws CImgArgumentException when both the FILE* and the filename are null, because there is no output target. It mirrors the same guard used by the other _save_* overloads.
Solutions
- Pass a non-null filename to save_pnk()
- Check fopen() return value before passing a FILE*
- Validate the output path before calling save_pnk()
Example fix
// before
std::FILE *f = std::fopen(path.c_str(), "wb");
img.save_pnk(f); // f may be NULL
// after
std::FILE *f = std::fopen(path.c_str(), "wb");
if (f) img.save_pnk(f); else throw std::runtime_error("cannot open " + path); Defensive patterns
Strategy: validation
Validate before calling
if (!file && (!filename || !*filename)) throw std::invalid_argument("save_pnk requires a filename or FILE*"); Type guard
bool hasDestination(std::FILE *f, const char *name) { return f != NULL || (name != NULL && name[0] != '\0'); } Try / catch
try { img.save_pnk(path.c_str()); } catch (CImgArgumentException &e) { /* handle */ } Prevention
- Guard all output paths at call sites
- Check fopen() before forwarding FILE*
- Use std::string instead of raw char* where possible
When it happens
Trigger: Calling save_pnk((std::FILE*)0), or _save_pnk with both arguments null; passing a FILE* returned NULL by fopen() without checking.
Common situations: fopen failure not checked before forwarding the stream; null path from environment/config; refactored code that dropped the filename parameter.
Related errors
- save_pfm(): Specified filename is (null).
- save_pnm(): Specified filename is (null).
- save_rgb(): Specified filename is (null).
- save_rgba(): Specified filename is (null).
- load_cimg(): Specified filename is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/65a803a3db205734.
Report an issue: GitHub.
Appendix: source
Thrown at ucrop/src/main/jni/CImg.h:62410
return *this;
}
//! Save image as a PNK file.
/**
\param filename Filename, as a C-string.
**/
const CImg<T>& save_pnk(const char *const filename) const {
return _save_pnk(0,filename);
}
//! Save image as a PNK file \overloading.
const CImg<T>& save_pnk(std::FILE *const file) const {
return _save_pnk(file,0);
}
const CImg<T>& _save_pnk(std::FILE *const file, const char *const filename) const {
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"save_pnk(): Specified filename is (null).",
cimg_instance);
if (is_empty()) { cimg::fempty(file,filename); return *this; }
if (_spectrum>1)
cimg::warn(_cimg_instance
"save_pnk(): Instance is multispectral, only the first channel will be saved in file '%s'.",
cimg_instance,
filename?filename:"(FILE*)");
const ulongT buf_size = std::min((ulongT)1024*1024,(ulongT)_width*_height*_depth);
std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
const T *ptr = data(0,0,0,0);
if (!cimg::type<T>::is_float() && sizeof(T)==1 && _depth<2) // Can be saved as regular PNM file
_save_pnm(file,filename,0);
else if (!cimg::type<T>::is_float() && sizeof(T)==1) { // Save as extended P5 file: Binary byte-valued 3D
std::fprintf(nfile,"P5\n%u %u %u\n255\n",_width,_height,_depth);
CImg<ucharT> buf((unsigned int)buf_size);View on GitHub (pinned to f788b534b4)