Yalantis/uCrop · error · CImgArgumentException

save_ascii(): Specified filename is (null).

Error message

save_ascii(): Specified filename is (null).

What it means

save_ascii() can write to either an open std::FILE* or a filename; _save_ascii() throws CImgArgumentException when BOTH are null because there is no output destination. It is the shared implementation behind save_ascii(std::FILE*) and save_ascii(filename).

Source

Thrown at ucrop/src/main/jni/CImg.h:61385

      return save_other(fn);
    }

    //! Save image as an ascii file.
    /**
      \param filename Filename, as a C-string.
    **/
    const CImg<T>& save_ascii(const char *const filename) const {
      return _save_ascii(0,filename);
    }

    //! Save image as an Ascii file \overloading.
    const CImg<T>& save_ascii(std::FILE *const file) const {
      return _save_ascii(file,0);
    }

    const CImg<T>& _save_ascii(std::FILE *const file, const char *const filename) const {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "save_ascii(): Specified filename is (null).",
                                    cimg_instance);
      std::FILE *const nfile = file?file:cimg::fopen(filename,"w");
      std::fprintf(nfile,"%u %u %u %u\n",_width,_height,_depth,_spectrum);
      const T* ptrs = _data;
      cimg_forYZC(*this,y,z,c) {
        cimg_forX(*this,x) std::fprintf(nfile,"%.17g ",(double)*(ptrs++));
        std::fputc('\n',nfile);
      }
      if (!file) cimg::fclose(nfile);
      return *this;
    }

    //! Save image as a .cpp source file.
    /**
      \param filename Filename, as a C-string.
    **/
    const CImg<T>& save_cpp(const char *const filename) const {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure fopen succeeded (non-NULL FILE*) before calling the FILE* overload.
  2. Call the filename overload (save_ascii("out.txt")) instead of the FILE* overload when no file is open.
  3. Check both file and filename are not null at the call site.
  4. Handle fopen errors (errno) before attempting to save.

Example fix

// before
FILE* f = fopen("out.txt", "w");
img.save_ascii(f); // f may be NULL
// after
FILE* f = fopen("out.txt", "w");
if (f) { img.save_ascii(f); fclose(f); }
else img.save_ascii("out.txt"); // fallback by filename
Defensive patterns

Strategy: type-guard

Validate before calling

if (!file && (!filename || !*filename)) { /* abort or fallback to default filename */ }

Type guard

bool hasDestination(std::FILE* f, const char* n){ return f!=nullptr || (n!=nullptr && *n!='\0'); }

Try / catch

try { img.save_ascii(f); } catch (CImgArgumentException& e) { /* reopen by filename fallback */ img.save_ascii("out.txt"); }

Prevention

When it happens

Trigger: Calling img.save_ascii((std::FILE*)NULL) or img.save_ascii((const char*)NULL); also a FILE* that failed fopen (returned NULL) forwarded into the FILE*-overload with no filename.

Common situations: fopen failure earlier in code whose NULL result was passed on, refactoring changed call from filename overload to FILE* overload passing 0, optional-output logic that skips creating a file but still calls save.

Related errors


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