File library for Bitmap images (*.bmp, *.dib). Currently supports only Windows V3 format with 24-bit-per-pixel color depth.

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;
+    }
+}