Yalantis/uCrop · error · CImgArgumentException

cimg::fempty(): Specified filename is (null).

Error message

cimg::fempty(): Specified filename is (null).

What it means

cimg::fempty() truncates/creates a file; it accepts either an open FILE* or a filename, but at least one must be non-NULL. It throws CImgArgumentException when both file and filename are NULL, because there is nothing to empty.

Source

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

        l_to_write = (to_write*sizeof(T))<wlimitT?to_write:wlimit;
        l_al_write = std::fwrite((void*)(ptr + al_write),sizeof(T),l_to_write,stream);
        al_write+=l_al_write;
        to_write-=l_al_write;
      } while (l_to_write==l_al_write && to_write>0);
      if (to_write>0)
        warn("cimg::fwrite(): Only %lu/%lu elements could be written in file.",
             (unsigned long)al_write,(unsigned long)nmemb);
      return al_write;
    }

    //! Create an empty file.
    /**
       \param file Input file (can be \c 0 if \c filename is set).
       \param filename Filename, as a C-string (can be \c 0 if \c file is set).
    **/
    inline void fempty(std::FILE *const file, const char *const filename) {
      if (!file && !filename)
        throw CImgArgumentException("cimg::fempty(): Specified filename is (null).");
      std::FILE *const nfile = file?file:cimg::fopen(filename,"wb");
      if (!file) cimg::fclose(nfile);
    }

    // Try to guess format from an image file.
    inline const char *ftype(std::FILE *const file, const char *const filename);

    // Get or set load from network mode (can be { 0=disabled | 1=enabled }).
    inline bool& network_mode(const bool value, const bool is_set) {
      static bool mode = true;
      if (is_set) { cimg::mutex(0); mode = value; cimg::mutex(0,0); }
      return mode;
    }

    inline bool& network_mode() {
      return network_mode(false,false);
    }

View on GitHub (pinned to f788b534b4)

Solutions

  1. Pass either a valid open std::FILE* or a non-NULL filename C-string
  2. If the filename may be absent, provide the already-open stream instead (or vice versa)
  3. Validate the input before calling and raise a clearer application-level error

Example fix

// before
cimg::fempty(file, filename); // both may be NULL
// after
if (file) cimg::fempty(file, 0);
else if (filename) cimg::fempty(0, filename);
else throw std::runtime_error("fempty needs a file or a filename");
Defensive patterns

Strategy: validation

Validate before calling

if (!file && (!filename || !*filename)) throw std::invalid_argument("fempty requires a file or filename");

Type guard

bool emptyable(std::FILE *f, const char *name){ return f || (name && *name); }

Try / catch

try { cimg::fempty(file, filename); } catch (const cimg_library::CImgArgumentException &e) { log_error("fempty misuse: %s", e.what()); }

Prevention

When it happens

Trigger: Calling cimg::fempty(NULL, NULL) — e.g. both the stream variable and the filename string are unset, or a helper forwards two optional parameters that are both missing.

Common situations: Refactored helper signatures where the filename argument was dropped; passing a std::string filename's c_str() from an empty optional wrapper; forgetting to open the file before calling fempty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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