BMP文件格式學習總結

一個BMP文件可以包含4部分

1,文件頭是14字節長的數據結構,定義如下:

typedef struct _BFHEADER
{
    unsigned short magic;
    unsigned int size;
    unsigned int reserved;
    unsigned int bitOffset;
}bfHeader;

2.bmp 信息結構,結構定義如下:

typedef struct _bmpInfoHead
{
    unsigned int headSize;
    unsigned int width;
    unsigned int height;
    unsigned short planes;
    unsigned short bpp;
    unsigned int compress;
    unsigned int imageSize;
    unsigned int PelsPerMeterX;
    unsigned int PelsPerMeterY;
    unsigned int ClrUsed;
    unsigned int ClrImportant;
    unsigned int RedMask;
    unsigned int GreenMask;
    unsigned int BlueMask;
    unsigned int AlphaMask;
    unsigned int CsType;
    unsigned int Endpoints[9]; // see http://msdn2.microsoft.com/en-us/library/ms536569.aspx
    unsigned int GammaRed;
    unsigned int GammaGreen;
    unsigned int GammaBlue;
}bmpInfoHead;

3.調色板palette

typedef struct _BGRA {
    unsigned char Blue;
    unsigned char Green;
    unsigned char Red;
    unsigned char Alpha;
} BGRA;

4.pixel Data

一個完整的簡單BMP reader程序如下:

#include<stdio.h>
#include<stdlib.h>
/*
Pixel format
The 1-bit per pixel (1bpp) format supports 2 distinct colors, (for example: black and white). The pixel values are stored in each bit, with the first (left-most) pixel in the most-significant bit of the first byte.[4] Each bit is an index into a table of 2 colors. An unset bit will refer to the first color table entry, and a set bit will refer to the last (second) color table entry.
The 2-bit per pixel (2bpp) format supports 4 distinct colors and stores 4 pixels per 1 byte, the left-most pixel being in the two most significant bits (Windows CE only:[19]). Each pixel value is a 2-bit index into a table of up to 4 colors.
The 4-bit per pixel (4bpp) format supports 16 distinct colors and stores 2 pixels per 1 byte, the left-most pixel being in the more significant nibble.[4] Each pixel value is a 4-bit index into a table of up to 16 colors.
The 8-bit per pixel (8bpp) format supports 256 distinct colors and stores 1 pixel per 1 byte. Each byte is an index into a table of up to 256 colors.
The 16-bit per pixel (16bpp) format supports 65536 distinct colors and stores 1 pixel per 2-byte WORD. Each WORD can define the alpha, red, green and blue samples of the pixel.
The 24-bit pixel (24bpp) format supports 16,777,216 distinct colors and stores 1 pixel value per 3 bytes. Each pixel value defines the red, green and blue samples of the pixel (8.8.8.0.0 in RGBAX notation). Specifically, in the order: blue, green and red (8 bits per each sample).[4]
The 32-bit per pixel (32bpp) format supports 4,294,967,296 distinct colors and stores 1 pixel per 4-byte DWORD. Each DWORD can define the alpha, red, green and blue samples of the pixel.
*/

#pragma pack(push, 1)

typedef struct _BFHEADER
{
    unsigned short magic;
    unsigned int size;
    unsigned int reserved;
    unsigned int bitOffset;
}bfHeader;

typedef struct _bmpInfoHead
{
    unsigned int headSize;
    unsigned int width;
    unsigned int height;
    unsigned short planes;
    unsigned short bpp;
    unsigned int compress;
    unsigned int imageSize;
    unsigned int PelsPerMeterX;
    unsigned int PelsPerMeterY;
    unsigned int ClrUsed;
    unsigned int ClrImportant;
    unsigned int RedMask;
    unsigned int GreenMask;
    unsigned int BlueMask;
    unsigned int AlphaMask;
    unsigned int CsType;
    unsigned int Endpoints[9]; // see http://msdn2.microsoft.com/en-us/library/ms536569.aspx
    unsigned int GammaRed;
    unsigned int GammaGreen;
    unsigned int GammaBlue;
}bmpInfoHead;

typedef struct _RGBA {
    unsigned char Red;
    unsigned char Green;
    unsigned char Blue;
    unsigned char Alpha;
} RGBA;

typedef struct _BGRA {
    unsigned char Blue;
    unsigned char Green;
    unsigned char Red;
    unsigned char Alpha;
} BGRA;


FILE *inFd;
bfHeader fHead;
bmpInfoHead bmpInfo;

BGRA *paletteTable;
BGRA *pixelData;
unsigned char *pixelLine;

int main(void)
{
    unsigned int ColorTableSize = 0;
    unsigned int linePixelLength;
    int count;
    int rdLen;
    //fgetc();
    inFd = fopen("testimg.bmp", "rb");
    rdLen = fread(&fHead, sizeof(fHead), 1,inFd);
    rdLen = fread(&bmpInfo, sizeof(bmpInfo), 1,inFd);
    
    switch (bmpInfo.bpp)
    {
    case 2:
        break;
    case 4:
        ColorTableSize = 16;
        break;
    case 8:
        ColorTableSize = 256;
    case 16:
        break;
    case 32:
        //true color each bit save RGB, do not need palette 
        break;
    default:
        break;
    }

    paletteTable = (BGRA *) malloc(ColorTableSize * sizeof(BGRA));
    pixelData = (BGRA *)malloc(sizeof(BGRA)*bmpInfo.height*bmpInfo.width);
    count=ftell(inFd);
    count = sizeof(fHead) + sizeof(bmpInfo);
    fseek(inFd, count, SEEK_SET);//from begin;
    //Read color map
    count= bmpInfo.ClrUsed * sizeof(BGRA);
    rdLen = fread(paletteTable, count, 1, inFd);

    linePixelLength = (bmpInfo.width*bmpInfo.bpp / 8);

    pixelLine = (unsigned char *)malloc(linePixelLength);

    fseek(inFd, fHead.bitOffset, SEEK_SET);//from begin;

    BGRA *p = pixelData;
    unsigned char color;
    for (unsigned int h = 0; h < bmpInfo.height; h++)
    {
        rdLen = fread(pixelLine, linePixelLength, 1, inFd);
        for (unsigned int w = 0; w < bmpInfo.width; w++)
        {
            color = pixelLine[w];
            p->Blue = paletteTable[color].Blue;
            p->Green = paletteTable[color].Green;
            p->Red = paletteTable[color].Red;
            p++;
        }
    }

    count++;


}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章