Yalantis/uCrop · warning

cimg::fwrite(): Only %lu/%lu elements could be written in fi

Error message

cimg::fwrite(): Only %lu/%lu elements could be written in file.

What it means

cimg::fwrite() writes nmemb elements of size sizeof(T) to a C stream in bounded chunks and emits a non-fatal warning when the stream accepted fewer elements than requested. The function returns the count actually written, so the warning indicates a short write (disk full, closed stream, quota exceeded) rather than throwing. CImg save routines use it when dumping pixel data.

Source

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

       \return Number of written elements.
       \note Similar to <tt>std::fwrite</tt> but may display warning messages if all elements could not be written.
    **/
    template<typename T>
    inline size_t fwrite(const T *ptr, const size_t nmemb, std::FILE *stream) {
      if (!ptr || !stream)
        throw CImgArgumentException("cimg::fwrite(): Invalid writing request of %u %s%s from buffer %p to file %p.",
                                    nmemb,cimg::type<T>::string(),nmemb>1?"s":"",ptr,stream);
      if (!nmemb) return 0;
      const size_t wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
      size_t to_write = nmemb, al_write = 0, l_to_write = 0, l_al_write = 0;
      do {
        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);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check fwrite()'s return value equals the requested element count and treat a shortfall as a save failure
  2. Free disk space or write to a different volume, then retry the save
  3. Verify the output stream is still open/writable before saving (ferror(), for pipes check the reader)
  4. Write to a temp file and atomically rename into place so partial writes never masquerade as a successful save

Example fix

// before
img.save("/mnt/data/out.bmp"); // disk full -> partial file, only a warning
// after
if (!img.save("/mnt/data/out.bmp.tmp")) throw std::runtime_error("save failed (short write?)");
std::rename("/mnt/data/out.bmp.tmp", "/mnt/data/out.bmp");
Defensive patterns

Strategy: validation

Validate before calling

if (!std::FILE* f = std::fopen(out, "wb")) throw std::runtime_error("cannot open output");
// after saving:
if (std::fflush(f) != 0 || std::ferror(f)) throw std::runtime_error("write failed");

Type guard

bool stream_writable(std::FILE* f) { return f && !std::ferror(f); }

Prevention

When it happens

Trigger: Calling CImg<T>::fwrite()/save routines when the output disk is full, the FILE* was closed or hit an error mid-write, the target is a pipe that broke, or a quota/filesystem limit stops the write partway.

Common situations: Saving images to a full disk or a small tmpfs, writing to a closed stdout/pipe (e.g. process at the other end exited), permission/quota issues on the output path.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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