diff --git a/src/omv/img/bmp.c b/src/omv/img/bmp.c index 1e2f4b9bb..05092cb88 100644 --- a/src/omv/img/bmp.c +++ b/src/omv/img/bmp.c @@ -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); } }