Yalantis/uCrop · error · CImgArgumentException
save(): Specified filename is (null).
Error message
save(): Specified filename is (null).
What it means
CImg<T>::save() requires a non-null filename string; passing NULL throws CImgArgumentException before any file I/O. The format is chosen by file extension, so a filename is mandatory (stdout saving uses the special "-" name, not NULL).
Source
Thrown at ucrop/src/main/jni/CImg.h:61253
}
}
disp._normalization = old_normalization;
return *this;
}
//! Save image as a file.
/**
\param filename Filename, as a C-string.
\param number When positive, represents an index added to the filename. Otherwise, no number is added.
\param digits Number of digits used for adding the number to the filename.
\note
- The used file format is defined by the file extension in the filename \p filename.
- Parameter \p number can be used to add a 6-digit number to the filename before saving.
**/
const CImg<T>& save(const char *const filename, const int number=-1, const unsigned int digits=6) const {
if (!filename)
throw CImgArgumentException(_cimg_instance
"save(): Specified filename is (null).",
cimg_instance);
// Do not test for empty instances, since .cimg format is able to manage empty instances.
const bool is_stdout = *filename=='-' && (!filename[1] || filename[1]=='.');
const char *const ext = cimg::split_filename(filename);
CImg<charT> nfilename(1024);
const char *const fn = is_stdout?filename:(number>=0)?cimg::number_filename(filename,number,digits,nfilename):
filename;
#ifdef cimg_save_plugin
cimg_save_plugin(fn);
#endif
#ifdef cimg_save_plugin1
cimg_save_plugin1(fn);
#endif
#ifdef cimg_save_plugin2
cimg_save_plugin2(fn);
#endifView on GitHub (pinned to f788b534b4)
Solutions
- Check the filename pointer for NULL before calling save().
- Use an empty-string/stdout convention ("-") instead of NULL when output destination is optional.
- Fix the upstream producer of the filename (config/env/API) that returned NULL.
- In C++, prefer std::string and pass .c_str() only after validation.
Example fix
// before
const char* name = getenv("OUT"); img.save(name); // NULL if unset
// after
const char* name = getenv("OUT");
if (name) img.save(name); else img.save("out.png"); Defensive patterns
Strategy: type-guard
Validate before calling
if (!filename || !*filename) { /* substitute default or abort */ } Type guard
bool validPath(const char* p){ return p!=nullptr && *p!='\0'; } Try / catch
try { img.save(name); } catch (CImgArgumentException& e) { fprintf(stderr,"Save failed: %s\n", e.what()); } Prevention
- Never pass raw getenv()/config results unchecked into save()
- Use std::string internally and only .c_str() after validation
- Adopt a default output filename when the configured one is missing
When it happens
Trigger: Calling img.save(NULL) directly, or passing a filename variable that was never initialized / returned NULL from a failed lookup into save().
Common situations: Filename built from a failed getenv() or config read returning NULL, C-string from a function that returns NULL on error, wrapping code forwarding optional path arguments unchecked.
Related errors
- save_ascii(): Specified filename is (null).
- save_cpp(): Specified filename is (null).
- save_dlm(): Specified filename is (null).
- save_bmp(): Specified filename is (null).
- save_webp(): Specified filename is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/c1474b6c407f03cd.
Report an issue: GitHub.