Yalantis/uCrop · error · CImgArgumentException
cimg::fread(): Invalid reading request of %u %s%s from file
Error message
cimg::fread(): Invalid reading request of %u %s%s from file %p to buffer %p.
What it means
cimg::fread() validates that both the destination buffer and the FILE* stream are non-NULL before reading, and throws CImgArgumentException naming the element count, element type, stream pointer, and buffer pointer. It catches calls like fread(NULL, 100, fp) or fread(buf, 100, NULL). Note that nmemb==0 is explicitly allowed and returns 0.
Source
Thrown at ucrop/src/main/jni/CImg.h:7895
return p + 1;
}
// Generate a numbered version of a filename.
inline char* number_filename(const char *const filename, const int number,
const unsigned int digits, char *const str);
//! Read data from file.
/**
\param[out] ptr Pointer to memory buffer that will contain the binary data read from file.
\param nmemb Number of elements to read.
\param stream File to read data from.
\return Number of read elements.
\note Same as <tt>std::fread()</tt> but may display warning message if all elements could not be read.
**/
template<typename T>
inline size_t fread(T *const ptr, const size_t nmemb, std::FILE *stream) {
if (!ptr || !stream)
throw CImgArgumentException("cimg::fread(): Invalid reading request of %u %s%s from file %p to buffer %p.",
nmemb,cimg::type<T>::string(),nmemb>1?"s":"",stream,ptr);
if (!nmemb) return 0;
const size_t wlimitT = 63*1024*1024, wlimit = wlimitT/sizeof(T);
size_t to_read = nmemb, al_read = 0, l_to_read = 0, l_al_read = 0;
do {
l_to_read = (to_read*sizeof(T))<wlimitT?to_read:wlimit;
l_al_read = std::fread((void*)(ptr + al_read),sizeof(T),l_to_read,stream);
al_read+=l_al_read;
to_read-=l_al_read;
} while (l_to_read==l_al_read && to_read>0);
if (to_read>0)
warn("cimg::fread(): Only %lu/%lu elements could be read from file.",
(unsigned long)al_read,(unsigned long)nmemb);
return al_read;
}
//! Write data to file.
/**View on GitHub (pinned to f788b534b4)
Solutions
- Fix the earlier failure that left the FILE* or buffer NULL (check the return of cimg::fopen / allocation)
- Check that the buffer allocation succeeded and is large enough for nmemb elements of sizeof(T)
- Ensure the stream is opened before reading and not closed prematurely
Example fix
// before
CImg<float> img; img.load(f); // f is NULL after failed open
// after
std::FILE *f = cimg::fopen(path, "rb"); // throws if it fails
if (f) { CImg<float> img; img.load(f); cimg::fclose(f); } Defensive patterns
Strategy: type-guard
Validate before calling
if (!f || !buf || nmemb == 0) { /* skip or raise app-level error */ } Type guard
template<typename T> bool readable(T *p, std::FILE *s){ return p && s; } Try / catch
try { n = cimg::fread(buf, nmemb, f); } catch (const cimg_library::CImgArgumentException &e) { log_error("bad fread request: %s", e.what()); } Prevention
- Always check the FILE* returned by cimg::fopen before reading
- Verify malloc/new results, especially for large buffers on mobile
- Never use a FILE* after fclose; set it to NULL to catch reuse
When it happens
Trigger: cimg::fread(ptr, nmemb, stream) with a NULL ptr (allocation failed or buffer freed early) or NULL stream (cimg::fopen failed earlier and its exception was ignored/caught without stopping the flow).
Common situations: Ignoring the throw from cimg::fopen and continuing to use the NULL handle; malloc/calloc returning NULL for huge sizes on Android NDK due to memory exhaustion; using a FILE* after fclose.
Related errors
- cimg::fopen(): Specified file path is (null).
- cimg::fopen(): File '%s', specified mode is (null).
- cimg::fwrite(): Invalid writing request of %u %s%s from buff
- cimg::fempty(): Specified filename is (null).
- draw_spline(): Specified color is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/01c73b59207732d5.
Report an issue: GitHub.