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);
#endif

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check the filename pointer for NULL before calling save().
  2. Use an empty-string/stdout convention ("-") instead of NULL when output destination is optional.
  3. Fix the upstream producer of the filename (config/env/API) that returned NULL.
  4. 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

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


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