Yalantis/uCrop · error · CImgIOException
load_bmp(): Invalid BMP file '%s'.
Error message
load_bmp(): Invalid BMP file '%s'.
What it means
load_bmp() reads the first 54 bytes and checks the 'BM' magic; a mismatch throws CImgIOException because the file is not a BMP. This fires before any header parsing, so it is purely a signature check.
Source
Thrown at ucrop/src/main/jni/CImg.h:56784
//! Load image from a BMP file \newinstance.
static CImg<T> get_load_bmp(std::FILE *const file) {
return CImg<T>().load_bmp(file);
}
CImg<T>& _load_bmp(std::FILE *const file, const char *const filename) {
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"load_bmp(): Specified filename is (null).",
cimg_instance);
const ulongT fsiz = (ulongT)(file?cimg::fsize(file):cimg::fsize(filename));
std::FILE *const nfile = file?file:cimg::fopen(filename,"rb");
CImg<ucharT> header(54);
cimg::fread(header._data,54,nfile);
if (*header!='B' || header[1]!='M') {
if (!file) cimg::fclose(nfile);
throw CImgIOException(_cimg_instance
"load_bmp(): Invalid BMP file '%s'.",
cimg_instance,
filename?filename:"(FILE*)");
}
// Read header and pixel buffer.
int
file_size = header[0x02] + (header[0x03]<<8) + (header[0x04]<<16) + (header[0x05]<<24),
offset = header[0x0A] + (header[0x0B]<<8) + (header[0x0C]<<16) + (header[0x0D]<<24),
header_size = header[0x0E] + (header[0x0F]<<8) + (header[0x10]<<16) + (header[0x11]<<24),
dx = header[0x12] + (header[0x13]<<8) + (header[0x14]<<16) + (header[0x15]<<24),
dy = header[0x16] + (header[0x17]<<8) + (header[0x18]<<16) + (header[0x19]<<24),
compression = header[0x1E] + (header[0x1F]<<8) + (header[0x20]<<16) + (header[0x21]<<24),
nb_colors = header[0x2E] + (header[0x2F]<<8) + (header[0x30]<<16) + (header[0x31]<<24),
bpp = header[0x1C] + (header[0x1D]<<8);
if ((ulongT)file_size!=fsiz)
throw CImgIOException(_cimg_instanceView on GitHub (pinned to f788b534b4)
Solutions
- Verify the file's first two bytes are 'BM' before calling load_bmp.
- Use img.load(path) to auto-detect the real format instead of forcing the BMP loader.
- Re-export or re-download the image if it is corrupt.
- Decode with a tolerant loader (e.g. BitmapFactory) and convert to BMP if BMP input is required.
Example fix
// before img.load_bmp(path); // after std::ifstream f(path, std::ios::binary); char m[2]; f.read(m,2); if (m[0]=='B' && m[1]=='M') img.load_bmp(path); else img.load(path); // auto-detect
Defensive patterns
Strategy: validation
Validate before calling
bool isBmpMagic(const char* p){ std::ifstream f(p,std::ios::binary); char m[2]={0}; f.read(m,2); return m[0]=='B'&&m[1]=='M'; } Try / catch
try { img.load_bmp(path); } catch (cimg_library::CImgIOException& e) { /* not a BMP: fall back to auto-detect */ img.load(path); } Prevention
- Validate 'BM' magic bytes before calling load_bmp
- Never trust file extensions; check content
- Use img.load() auto-detection when format is uncertain
When it happens
Trigger: img.load_bmp(path) on a file whose first two bytes are not 'B','M' — e.g. a PNG/JPEG renamed to .bmp, a corrupted download, or a file starting with a BOM.
Common situations: Relying on file extension instead of actual content; build scripts copying wrong assets; partial writes that truncated the header.
Related errors
- load(): Failed to recognize format of file '%s'.
- load_ascii(): Invalid ascii header in file '%s', image dimen
- load_dlm(): Invalid DLM file '%s'.
- load_bmp(): Specified filename is (null).
- load_bmp(): Invalid file_size %d specified in filename '%s'
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/4791826ed6f2e6aa.
Report an issue: GitHub.