Fix bmp file reading for all formats

This commit is contained in:
Kwabena W. Agyeman 2019-10-10 14:50:36 -07:00
parent ad4da07d70
commit 466a50a003

View File

@ -33,7 +33,13 @@ bool bmp_read_geometry(FIL *fp, image_t *img, const char *path, bmp_read_setting
uint32_t data_size = file_size - header_size;
if (data_size % 4) ff_file_corrupted(fp);
read_long_expect(fp, 40);
uint32_t header_type;
read_long(fp, &header_type);
if ((header_type != 40) // BITMAPINFOHEADER
&& (header_type != 52) // BITMAPV2INFOHEADER
&& (header_type != 56) // BITMAPV3INFOHEADER
&& (header_type != 108) // BITMAPV4HEADER
&& (header_type != 124)) ff_unsupported_format(fp); // BITMAPV5HEADER
read_long(fp, (uint32_t*) &rs->bmp_w);
read_long(fp, (uint32_t*) &rs->bmp_h);
if ((rs->bmp_w == 0) || (rs->bmp_h == 0)) ff_file_corrupted(fp);
@ -56,6 +62,18 @@ bool bmp_read_geometry(FIL *fp, image_t *img, const char *path, bmp_read_setting
if (rs->bmp_bpp == 8) {
if (rs->bmp_fmt != 0) ff_unsupported_format(fp);
if (header_type >= 52) { // Skip past the remaining BITMAPV2INFOHEADER bytes.
for (int i = 0; i < 3; i++) read_long_ignore(fp);
}
if (header_type >= 56) { // Skip past the remaining BITMAPV3INFOHEADER bytes.
for (int i = 0; i < 1; i++) read_long_ignore(fp);
}
if (header_type >= 108) { // Skip past the remaining BITMAPV4HEADER bytes.
for (int i = 0; i < 13; i++) read_long_ignore(fp);
}
if (header_type >= 124) { // Skip past the remaining BITMAPV5HEADER bytes.
for (int i = 0; i < 4; i++) read_long_ignore(fp);
}
// Color Table (1024 bytes)
for (int i = 0; i < 256; i++) {
read_long_expect(fp, ((i) << 16) | ((i) << 8) | i);
@ -66,12 +84,32 @@ bool bmp_read_geometry(FIL *fp, image_t *img, const char *path, bmp_read_setting
read_long_expect(fp, 0x1F << 11);
read_long_expect(fp, 0x3F << 5);
read_long_expect(fp, 0x1F);
if (header_type >= 56) { // Skip past the remaining BITMAPV3INFOHEADER bytes.
for (int i = 0; i < 1; i++) read_long_ignore(fp);
}
if (header_type >= 108) { // Skip past the remaining BITMAPV4HEADER bytes.
for (int i = 0; i < 13; i++) read_long_ignore(fp);
}
if (header_type >= 124) { // Skip past the remaining BITMAPV5HEADER bytes.
for (int i = 0; i < 4; i++) read_long_ignore(fp);
}
} else if (rs->bmp_bpp == 24) {
if (rs->bmp_fmt == 3) {
// Bit Masks (12 bytes)
read_long_expect(fp, 0xFF << 16);
read_long_expect(fp, 0xFF << 8);
read_long_expect(fp, 0xFF);
} else if (header_type >= 52) { // Skip past the remaining BITMAPV2INFOHEADER bytes.
for (int i = 0; i < 3; i++) read_long_ignore(fp);
}
if (header_type >= 56) { // Skip past the remaining BITMAPV3INFOHEADER bytes.
for (int i = 0; i < 1; i++) read_long_ignore(fp);
}
if (header_type >= 108) { // Skip past the remaining BITMAPV4HEADER bytes.
for (int i = 0; i < 13; i++) read_long_ignore(fp);
}
if (header_type >= 124) { // Skip past the remaining BITMAPV5HEADER bytes.
for (int i = 0; i < 4; i++) read_long_ignore(fp);
}
}