The notice of reading bitmap under Linux

Time:2020-2-25

The notice of reading bitmap under Linux

The problem of reading bitmap under Linux reflects the difference between Linux and windows. It is reasonable to say that the bitmap format is independent of the operating system and reading. In fact, when the bitmap is read into memory, it is different. The following mainly introduces the problems encountered in operating bitmaps under Linux.

(1) , bitmap structure

At the beginning, bitmaps are two structures, including the details of bitmaps, which is the key to read the later data. Therefore, to read a bitmap, you must first read the two structures correctly: bitmapfileheader and BITMAPINFOHEADER. It is specifically defined as:


typedef struct tagBITMAPFILEHEADER 
{ // bmfh 
  WORD  bfType; 
  DWORD  bfSize; 
  WORD  bfReserved1; 
  WORD  bfReserved2; 
  DWORD  bfOffBits; 
}__attribute__ ((packed))BITMAPFILEHEADER; 
typedef struct tagBITMAPINFOHEADER 
{ // bmih 
  DWORD biSize; 
  LONG  biWidth; 
  LONG  biHeight; 
  WORD  biPlanes; 
  WORD  biBitCount; 
  DWORD biCompression; 
  DWORD biSizeImage; 
  LONG  biXPelsPerMeter; 
  LONG  biYPelsPerMeter; 
  DWORD biClrUsed; 
  DWORD biClrImportant; 
}__attribute__ ((packed))BITMAPINFOHEADER; 

The above two structures can be used normally under windows. However, there are no variable types such as word and DWORD under Linux, so we need to map these variables to common variable types under Linux:


typedef unsigned short WORD; 
typedef unsigned int DWORD; 
typedef int LONG;//use int not long here!!! 
typedef unsigned char BYTE; 

The above mapping pays special attention to the number of bytes of each type. Different operating system variables have different length. We need to use sizeof to get the variable type length of the machine first, and then select the appropriate variable type according to the length of each attribute of the bitmap. The third variable long here is four bytes in windows, but eight bytes in Linux, so we need to use int instead of long.

(2) , alignment

In the definition of bitmap structure, we add the statement “attribute” (packed) before the structure name. __The function of attribute (packed)) is to tell the compiler to cancel the optimized alignment of structure during compilation and align according to the actual number of bytes, which is a special syntax of GCC. In windows, the read operation will not be optimized and will be read according to the actual size of the structure. However, in Linux, in order to speed up the access speed, the alignment operation of access will be enabled. At this time, the size of the structure in memory is larger than the original definition. If you access the bitmap property according to the previous size, you will read the wrong value. For easy access, we need to disable alignment optimization.

(3) , bitmap data

For 24 bit true color bitmaps, bitmaps do not include color palettes, and the bitmap data is the RGB color value. So many people think that the data size is 3 * height * width, which is used directly when reading data, but this is wrong. Each line of 24 bit true color bitmap also needs to meet one condition: the data length can be divided by 4, otherwise it needs to be supplemented with 0 to be divided by 4. Therefore, the reading process needs to be completed line by line, and at the end of each line, we need to skip a certain number of zeros. The calculation formula is as follows:


    skip=(4-(3*width)%4)%4;

In C language, the reading process is as follows:


for(int i=0;i<height;i++) 
{ 
  fread(p,sizeof(unsigned char)*width*3,1,fp); 
  p+=sizeof(unsigned char)*width)*3; 
  fseek(fp,skip*sizeof(unsigned char),SEEK_CUR); 
 
} 

(4) , RGB order

As mentioned before, 24 bit true color bitmaps do not include color palettes. Bitmap data is the value of RGB color, and each color occupies one byte. At this time, many people think that the order of colors is r, G and B, but this is also wrong. The actual order should be B, G and r. This also requires special attention.

Thank you for reading, hope to help you, thank you for your support!