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

Committer:
kayekss
Date:
Wed Mar 04 00:29:12 2015 +0000
Revision:
0:4617bf407fe5
Child:
1:8cf4beca9695
Initial release.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kayekss 0:4617bf407fe5 1 // ==================================================== Mar 04 2015, kayeks ==
kayekss 0:4617bf407fe5 2 // BMPFile.cpp
kayekss 0:4617bf407fe5 3 // ===========================================================================
kayekss 0:4617bf407fe5 4 // File library for Bitmap images (*.bmp, *.dib).
kayekss 0:4617bf407fe5 5
kayekss 0:4617bf407fe5 6 #include "BMPFile.h"
kayekss 0:4617bf407fe5 7
kayekss 0:4617bf407fe5 8 const char* BMPFile::StatusString[] = {
kayekss 0:4617bf407fe5 9 "Success",
kayekss 0:4617bf407fe5 10 "NullFileName",
kayekss 0:4617bf407fe5 11 "NoSuchFile",
kayekss 0:4617bf407fe5 12 "NotABitmapFile",
kayekss 0:4617bf407fe5 13 "UnsupportedFormat",
kayekss 0:4617bf407fe5 14 "UnsupportedDepth",
kayekss 0:4617bf407fe5 15 "AllocationFailed"
kayekss 0:4617bf407fe5 16 };
kayekss 0:4617bf407fe5 17 const char* BMPFile::FormatString[] = {
kayekss 0:4617bf407fe5 18 "Windows_V3",
kayekss 0:4617bf407fe5 19 "Windows_V4",
kayekss 0:4617bf407fe5 20 "Windows_V5",
kayekss 0:4617bf407fe5 21 "OS2_V1",
kayekss 0:4617bf407fe5 22 "OS2_V2",
kayekss 0:4617bf407fe5 23 "Unknown"
kayekss 0:4617bf407fe5 24 };
kayekss 0:4617bf407fe5 25
kayekss 0:4617bf407fe5 26 BMPFile::BMPFile(const char* filename) {
kayekss 0:4617bf407fe5 27 FILE* fp;
kayekss 0:4617bf407fe5 28 uint8_t buf8[2];
kayekss 0:4617bf407fe5 29 uint16_t buf16[2];
kayekss 0:4617bf407fe5 30 uint32_t buf32[3];
kayekss 0:4617bf407fe5 31 uint32_t offset;
kayekss 0:4617bf407fe5 32
kayekss 0:4617bf407fe5 33 status = Success;
kayekss 0:4617bf407fe5 34 format = Unknown;
kayekss 0:4617bf407fe5 35 fileSize = 0;
kayekss 0:4617bf407fe5 36 dataSize = 0;
kayekss 0:4617bf407fe5 37 width = 0;
kayekss 0:4617bf407fe5 38 height = 0;
kayekss 0:4617bf407fe5 39 colorDepth = 0;
kayekss 0:4617bf407fe5 40 data = NULL;
kayekss 0:4617bf407fe5 41
kayekss 0:4617bf407fe5 42 // Open file
kayekss 0:4617bf407fe5 43 if (!filename) {
kayekss 0:4617bf407fe5 44 status = NullFilename;
kayekss 0:4617bf407fe5 45 return;
kayekss 0:4617bf407fe5 46 }
kayekss 0:4617bf407fe5 47 fp = fopen(filename, "rb");
kayekss 0:4617bf407fe5 48 if (!fp) {
kayekss 0:4617bf407fe5 49 status = NoSuchFile;
kayekss 0:4617bf407fe5 50 return;
kayekss 0:4617bf407fe5 51 }
kayekss 0:4617bf407fe5 52
kayekss 0:4617bf407fe5 53 // (0 +2) Magic number ("BM")
kayekss 0:4617bf407fe5 54 fread(buf8, 1, 2, fp);
kayekss 0:4617bf407fe5 55 if (buf8[0] != 'B' || buf8[1] != 'M') {
kayekss 0:4617bf407fe5 56 status = NotABitmapFile;
kayekss 0:4617bf407fe5 57 fclose(fp);
kayekss 0:4617bf407fe5 58 return;
kayekss 0:4617bf407fe5 59 }
kayekss 0:4617bf407fe5 60
kayekss 0:4617bf407fe5 61 // (2 +4) File size
kayekss 0:4617bf407fe5 62 // (6 +4) Reserved area
kayekss 0:4617bf407fe5 63 // (10 +4) Image data offset (unconfirmed)
kayekss 0:4617bf407fe5 64 fread(buf32, 4, 3, fp);
kayekss 0:4617bf407fe5 65 fileSize = buf32[0];
kayekss 0:4617bf407fe5 66 offset = buf32[2];
kayekss 0:4617bf407fe5 67
kayekss 0:4617bf407fe5 68 // (14 +4) Header size
kayekss 0:4617bf407fe5 69 fread(buf32, 4, 1, fp);
kayekss 0:4617bf407fe5 70 switch (buf32[0]) {
kayekss 0:4617bf407fe5 71 case 40: // Windows V3 format
kayekss 0:4617bf407fe5 72 format = Windows_V3;
kayekss 0:4617bf407fe5 73 break;
kayekss 0:4617bf407fe5 74 case 108: // Windows V4 format
kayekss 0:4617bf407fe5 75 format = Windows_V4;
kayekss 0:4617bf407fe5 76 break;
kayekss 0:4617bf407fe5 77 case 124: // Windows V5 format
kayekss 0:4617bf407fe5 78 format = Windows_V5;
kayekss 0:4617bf407fe5 79 break;
kayekss 0:4617bf407fe5 80 case 12: // OS/2 V1 format
kayekss 0:4617bf407fe5 81 format = OS2_V1;
kayekss 0:4617bf407fe5 82 break;
kayekss 0:4617bf407fe5 83 case 64: // OS/2 V2 format
kayekss 0:4617bf407fe5 84 format = OS2_V2;
kayekss 0:4617bf407fe5 85 break;
kayekss 0:4617bf407fe5 86 default:
kayekss 0:4617bf407fe5 87 format = Unknown;
kayekss 0:4617bf407fe5 88 }
kayekss 0:4617bf407fe5 89
kayekss 0:4617bf407fe5 90 switch (format) {
kayekss 0:4617bf407fe5 91 case Windows_V3:
kayekss 0:4617bf407fe5 92 // (18 +4) Bitmap width
kayekss 0:4617bf407fe5 93 // (22 +4) Bitmap height
kayekss 0:4617bf407fe5 94 fread(buf32, 4, 2, fp);
kayekss 0:4617bf407fe5 95 width = buf32[0];
kayekss 0:4617bf407fe5 96 height = buf32[1];
kayekss 0:4617bf407fe5 97
kayekss 0:4617bf407fe5 98 // (26 +2) Number of planes (unconfirmed)
kayekss 0:4617bf407fe5 99 // (28 +2) Color depth
kayekss 0:4617bf407fe5 100 fread(buf16, 2, 2, fp);
kayekss 0:4617bf407fe5 101 colorDepth = buf16[1];
kayekss 0:4617bf407fe5 102 if (colorDepth != 24) {
kayekss 0:4617bf407fe5 103 status = UnsupportedDepth;
kayekss 0:4617bf407fe5 104 fclose(fp);
kayekss 0:4617bf407fe5 105 return;
kayekss 0:4617bf407fe5 106 }
kayekss 0:4617bf407fe5 107
kayekss 0:4617bf407fe5 108 // (30 +4) Compression method (unconfirmed)
kayekss 0:4617bf407fe5 109 // (34 +4) Bitmap data size (unconfirmed)
kayekss 0:4617bf407fe5 110 // (38 +4) Horizontal resolution (unused)
kayekss 0:4617bf407fe5 111 // (42 +4) Vertical resolution (unconfirmed)
kayekss 0:4617bf407fe5 112 // (46 +4) Colors (unconfirmed)
kayekss 0:4617bf407fe5 113 // (50 +4) Important colors (unconfirmed)
kayekss 0:4617bf407fe5 114 fread(buf32, 4, 3, fp);
kayekss 0:4617bf407fe5 115 fread(buf32, 4, 3, fp);
kayekss 0:4617bf407fe5 116 break;
kayekss 0:4617bf407fe5 117 case Windows_V4:
kayekss 0:4617bf407fe5 118 case Windows_V5:
kayekss 0:4617bf407fe5 119 case OS2_V1:
kayekss 0:4617bf407fe5 120 case OS2_V2:
kayekss 0:4617bf407fe5 121 case Unknown:
kayekss 0:4617bf407fe5 122 status = UnsupportedFormat;
kayekss 0:4617bf407fe5 123 fclose(fp);
kayekss 0:4617bf407fe5 124 return;
kayekss 0:4617bf407fe5 125 }
kayekss 0:4617bf407fe5 126 // Seek to image data offset
kayekss 0:4617bf407fe5 127 fseek(fp, offset, SEEK_SET);
kayekss 0:4617bf407fe5 128
kayekss 0:4617bf407fe5 129 // Calculate data length
kayekss 0:4617bf407fe5 130 dataSize = ((colorDepth / 8) * width + 3) / 4 * 4 * height;
kayekss 0:4617bf407fe5 131
kayekss 0:4617bf407fe5 132 // Allocate data space
kayekss 0:4617bf407fe5 133 data = new uint8_t[dataSize];
kayekss 0:4617bf407fe5 134
kayekss 0:4617bf407fe5 135 // Read bitmap data
kayekss 0:4617bf407fe5 136 fread(data, 1, dataSize, fp);
kayekss 0:4617bf407fe5 137
kayekss 0:4617bf407fe5 138 fclose(fp);
kayekss 0:4617bf407fe5 139 }
kayekss 0:4617bf407fe5 140
kayekss 0:4617bf407fe5 141 BMPFile::~BMPFile() {
kayekss 0:4617bf407fe5 142 if (data) {
kayekss 0:4617bf407fe5 143 delete[] data;
kayekss 0:4617bf407fe5 144 }
kayekss 0:4617bf407fe5 145 }