Yalantis/uCrop · error · CImgArgumentException

save_bmp(): Specified filename is (null).

Error message

save_bmp(): Specified filename is (null).

What it means

save_bmp() writes a Windows BMP file; _save_bmp() throws CImgArgumentException when both the FILE* and filename are null — no output destination was specified. BMP needs either an open stream or a path to open itself.

Source

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

      return *this;
    }

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

    //! Save image as a BMP file \overloading.
    const CImg<T>& save_bmp(std::FILE *const file) const {
      return _save_bmp(file,0);
    }

    const CImg<T>& _save_bmp(std::FILE *const file, const char *const filename) const {
      if (!file && !filename)
        throw CImgArgumentException(_cimg_instance
                                    "save_bmp(): Specified filename is (null).",
                                    cimg_instance);
      if (is_empty()) { cimg::fempty(file,filename); return *this; }
      if (_depth>1)
        cimg::warn(_cimg_instance
                   "save_bmp(): Instance is volumetric, only the first slice will be saved in file '%s'.",
                   cimg_instance,
                   filename?filename:"(FILE*)");
      if (_spectrum>3)
        cimg::warn(_cimg_instance
                   "save_bmp(): Instance is multispectral, only the three first channels will be saved in file '%s'.",
                   cimg_instance,
                   filename?filename:"(FILE*)");

      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
      CImg<ucharT> header(54,1,1,1,0);
      unsigned char align_buf[4] = {};
      const unsigned int

View on GitHub (pinned to f788b534b4)

Solutions

  1. Pass a valid filename, e.g., img.save_bmp("shot.bmp").
  2. Check fopen returned non-NULL before using the FILE* overload.
  3. Null-check both arguments at the call site.
  4. Write to stdout with the "-" filename if streaming output is intended.

Example fix

// before
img.save_bmp(file); // file==NULL when fopen failed
// after
if (file) img.save_bmp(file); else img.save_bmp("output.bmp");
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

try { img.save_bmp(f); } catch (CImgArgumentException& e) { img.save_bmp("output.bmp"); }

Prevention

When it happens

Trigger: img.save_bmp((std::FILE*)NULL) or img.save_bmp((const char*)NULL); forwarding a NULL FILE* from failed fopen into the stream overload.

Common situations: Screenshot/image export with a destination path from user input that was empty and converted to NULL; fopen permission errors.

Related errors


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