Yalantis/uCrop · error · CImgException
load_tiff(): Failed to allocate memory (%s) for file '%s'.
Error message
load_tiff(): Failed to allocate memory (%s) for file '%s'.
What it means
In the RGBA fast path, load_tiff() allocates a raster buffer of nx*ny*sizeof(cimg_uint32) bytes with _TIFFmalloc. If that allocation returns null, the library throws a CImgException naming the requested buffer size, meaning the system could not supply that much memory.
Source
Thrown at ucrop/src/main/jni/CImg.h:58194
voxel_size[1] = 1.f/voxel_size[1];
}
if (description) {
const char *s_description = 0;
if (TIFFGetField(tif,TIFFTAG_IMAGEDESCRIPTION,&s_description) && s_description)
CImg<charT>::string(s_description).move_to(*description);
}
const unsigned int spectrum = !is_spp || photo>=3?(photo>1?3:1):samplesperpixel;
assign(nx,ny,1,spectrum);
if ((photo>=3 && sampleformat==1 &&
(bitspersample==4 || bitspersample==8) &&
(samplesperpixel==1 || samplesperpixel==3 || samplesperpixel==4)) ||
(bitspersample==1 && samplesperpixel==1)) {
// Special case for unsigned color images.
cimg_uint32 *const raster = (cimg_uint32*)_TIFFmalloc(nx*ny*sizeof(cimg_uint32));
if (!raster) {
_TIFFfree(raster); TIFFClose(tif);
throw CImgException(_cimg_instance
"load_tiff(): Failed to allocate memory (%s) for file '%s'.",
cimg_instance,
cimg::strbuffersize(nx*ny*sizeof(cimg_uint32)),filename);
}
TIFFReadRGBAImage(tif,nx,ny,raster,0);
switch (spectrum) {
case 1 :
cimg_forXY(*this,x,y)
(*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny - 1 -y) + x]);
break;
case 3 :
cimg_forXY(*this,x,y) {
(*this)(x,y,0) = (T)(float)TIFFGetR(raster[nx*(ny - 1 - y) + x]);
(*this)(x,y,1) = (T)(float)TIFFGetG(raster[nx*(ny - 1 - y) + x]);
(*this)(x,y,2) = (T)(float)TIFFGetB(raster[nx*(ny - 1 - y) + x]);
}
break;
case 4 :View on GitHub (pinned to f788b534b4)
Solutions
- Free memory or reduce concurrent allocations before loading.
- Downscale or crop the image before load (e.g. preprocess with tiffcp -Z or vips).
- Load the image on a device/process with a larger memory budget (64-bit).
- Use the tile/strip read path instead of the RGBA path by changing the file's storage layout.
Example fix
// before: 40000x40000 RGBA => ~6.4 GB raster
img.load_tiff("huge_scan.tif");
// after: downscale first
// $ tiffcp -Z 8000 huge_scan.tif small.tif
img.load_tiff("small.tif"); Defensive patterns
Strategy: validation
Validate before calling
long long need = (long long)width * height * 4;
if (need > availableMemoryBudget()) throw std::runtime_error("TIFF too large for memory budget"); Try / catch
try { img.load_tiff(path); }
catch (CImgException &e) { if (strstr(e.what(), "allocate memory")) downscaleThenReload(path); else throw; } Prevention
- Estimate nx*ny*4 and compare to device memory before loading
- Downscale huge scans before load
- Avoid 32-bit processes for very large images
- Watch for integer overflow in size computations
When it happens
Trigger: Loading a very large TIFF (huge width*height) such that nx*ny*4 bytes exceeds available memory, e.g. a multi-gigapixel scan on a memory-constrained Android device.
Common situations: Mobile/JNI environments with low per-process memory limits, 32-bit address-space exhaustion, or 32-bit overflow of nx*ny*sizeof() for gigantic dimensions.
Related errors
- CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%
- load_tiff(): Specified filename is (null).
- load_tiff(): Unable to read sub-images from file '%s' unless
- load_tiff(): Failed to open file '%s'.
- load_tiff(): Invalid tile in file '%s'.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/15fa510ef8f8cdf9.
Report an issue: GitHub.