Load BMP data (for heightmaps etc)

From Sidvind
Jump to: navigation, search

Overview[edit]

BMP is a simple image format developed by Microsoft. The colordepth wary between 2 (1-bit), 16 (4-bit), 256 (8-bit), 16-bit and 24-bit. The image is usually not compressed, but it might be compressed with the RLE algorithm. This tutorial will cover how to read pixels from a BMP image into an 2-dimensional array.

File format[edit]

File header[edit]

Offset Bytes Description C/C++ datatype
0x00 - 0x01 2 This bytes must contain the ASCII character 'B' and 'M' Char
0x02 - 0x05 4 Size of the file in bytes Integer
0x06 - 0x07 4 Reserved, must be zero
0x08 - 0x09 4 Reserved, must be zero
0x0A - 0x0D 4 Offset to pixeldata Integer

Image header[edit]

Offset Bytes Description C/C++ datatype
0x0E - 0x11 4 Size of the image header, must be 40 (0x28) Integer
0x12 - 0x15 4 Image width in pixels Integer
0x16 - 0x19 4 Image height in pixels Integer
0x1A - 0x1B 4 Nr of planes, must be one Integer
0x1C - 0x1D 4 Bits per pixel, must be 1,2,4,8,16,24 or 32 Integer
0x1E - 0x21 4 Compression

0 = No compression 1 = RLE compression for 8bit bitmaps 2 = RLE compression for 4bit bitmaps Integer Following fields may be ignored most of the time. They is used to describe and store the palette. ||

0x22 - 0x25 4 Size of image data, may be zero if no compression is used Integer
0x26 - 0x29 4 Horizontal resolution of the image Integer
0x2A - 0x2D 4 Vertical resolution of the image Integer
0x2E - 0x31 4 Number of color indexes actually used, if set to zero all colors is used Integer
0x32 - 0x35 4 Nr of colors indexes required to render the image, if set to zero all color is used Integer
0x36 - 4 Optional: This part may contain the palette used by the image.

The format is RGBx (x is 1 byte reserved, must be set to zero) ||

Reading the header[edit]

The first step to read our image is to read its header to find out its size,bits-per-pixel and encoding. We will begin by making a simple struct to hold our data and a couple of enumerations for eventual errors. Lets start with struct.

Code:

  1. typedef struct Bitmap {
  2.         int offset;
  3.         int width;
  4.         int height;
  5.         int bpp;
  6.         int encoding;
  7.         int size;
  8.         bool loaded;
  9.         unsigned char* pData;
  10. };

For now this is all we need to store, but we will add more later. I don't think any of these need any further explanation.

Code:

  1. enum BITMAP_RESULTS {
  2.         BMP_OK,
  3.         BMP_NO_FILE,
  4.         BMP_INVALID_HEADER,
  5.         BMP_OUT_OF_MEMORY,
  6.         BMP_UNSUPPORTED,
  7.         BMP_LOADED,
  8. };

The first enum simply indicates everythings good soo far. BMP_NO_FILE means the file could not be opened, most likely the file doesn't exist but it might be permission error. BMP_INVALID_HEADER tells us the file isn't a valid BMP file, either it doesn't start with BM or the length is wrong. BMP_OUT_OF_MEMORY is self explanary. BMP_UNSUPPORTED is going to be used when the bpp has weired modes and/or encodings. The last one, BMP_LOADED, is used when there is already a bitmap loaded.

In order to read the header we first need to load the file into memory:

Code:

  1. #include <fstream>
  2.  
  3. using namespace std;
  4.  
  5. int loadBMP(Bitmap* img,char* filename){
  6.         ifstream::pos_type size
  7.         ifstream file(filename, ios::in|ios::binary|ios::ate);
  8.         if(file.is_open()){
  9.                 size = file.tellg();
  10.                 memblock = new char [size];
  11.                 file.seekg (0, ios::beg);
  12.                 file.read (memblock, size);
  13.                 file.close();
  14.         }
  15. }

Loading 8-bit monocrome image[edit]

TBD

Loading 24-bit truecolor image[edit]

TBD

Summary[edit]

TBD