File library for Bitmap images (*.bmp, *.dib). Currently supports only Windows V3 format with 24-bit-per-pixel color depth.
Diff: BMPFile.cpp
- Revision:
- 0:4617bf407fe5
- Child:
- 1:8cf4beca9695
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BMPFile.cpp Wed Mar 04 00:29:12 2015 +0000 @@ -0,0 +1,145 @@ +// ==================================================== Mar 04 2015, kayeks == +// BMPFile.cpp +// =========================================================================== +// File library for Bitmap images (*.bmp, *.dib). + +#include "BMPFile.h" + +const char* BMPFile::StatusString[] = { + "Success", + "NullFileName", + "NoSuchFile", + "NotABitmapFile", + "UnsupportedFormat", + "UnsupportedDepth", + "AllocationFailed" +}; +const char* BMPFile::FormatString[] = { + "Windows_V3", + "Windows_V4", + "Windows_V5", + "OS2_V1", + "OS2_V2", + "Unknown" +}; + +BMPFile::BMPFile(const char* filename) { + FILE* fp; + uint8_t buf8[2]; + uint16_t buf16[2]; + uint32_t buf32[3]; + uint32_t offset; + + status = Success; + format = Unknown; + fileSize = 0; + dataSize = 0; + width = 0; + height = 0; + colorDepth = 0; + data = NULL; + + // Open file + if (!filename) { + status = NullFilename; + return; + } + fp = fopen(filename, "rb"); + if (!fp) { + status = NoSuchFile; + return; + } + + // (0 +2) Magic number ("BM") + fread(buf8, 1, 2, fp); + if (buf8[0] != 'B' || buf8[1] != 'M') { + status = NotABitmapFile; + fclose(fp); + return; + } + + // (2 +4) File size + // (6 +4) Reserved area + // (10 +4) Image data offset (unconfirmed) + fread(buf32, 4, 3, fp); + fileSize = buf32[0]; + offset = buf32[2]; + + // (14 +4) Header size + fread(buf32, 4, 1, fp); + switch (buf32[0]) { + case 40: // Windows V3 format + format = Windows_V3; + break; + case 108: // Windows V4 format + format = Windows_V4; + break; + case 124: // Windows V5 format + format = Windows_V5; + break; + case 12: // OS/2 V1 format + format = OS2_V1; + break; + case 64: // OS/2 V2 format + format = OS2_V2; + break; + default: + format = Unknown; + } + + switch (format) { + case Windows_V3: + // (18 +4) Bitmap width + // (22 +4) Bitmap height + fread(buf32, 4, 2, fp); + width = buf32[0]; + height = buf32[1]; + + // (26 +2) Number of planes (unconfirmed) + // (28 +2) Color depth + fread(buf16, 2, 2, fp); + colorDepth = buf16[1]; + if (colorDepth != 24) { + status = UnsupportedDepth; + fclose(fp); + return; + } + + // (30 +4) Compression method (unconfirmed) + // (34 +4) Bitmap data size (unconfirmed) + // (38 +4) Horizontal resolution (unused) + // (42 +4) Vertical resolution (unconfirmed) + // (46 +4) Colors (unconfirmed) + // (50 +4) Important colors (unconfirmed) + fread(buf32, 4, 3, fp); + fread(buf32, 4, 3, fp); + break; + case Windows_V4: + case Windows_V5: + case OS2_V1: + case OS2_V2: + case Unknown: + status = UnsupportedFormat; + fclose(fp); + return; + } + // Seek to image data offset + fseek(fp, offset, SEEK_SET); + + // Calculate data length + dataSize = ((colorDepth / 8) * width + 3) / 4 * 4 * height; + + // Allocate data space + data = new uint8_t[dataSize]; + + // Read bitmap data + fread(data, 1, dataSize, fp); + + fclose(fp); +} + +BMPFile::~BMPFile() { + if (data) { + delete[] data; + } +}