/* All Rights Reserved Author:fanping.deng@gmail.com Function: convert RGB565 to BMP Build by g++
*/ #include <unistd.h> #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> typedef short WORD; typedef int DWORD; typedef int LONG; typedef char BYTE; //BITMAP File Header info typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; }__attribute__((packed)) BITMAPFILEHEADER; //Bitmap info header 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; typedef struct tagPaletteRGB { BYTE b; BYTE g; BYTE r; BYTE reserved; }__attribute__((packed)) paletteRGB; int g_len = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//+sizeof(paletteRGB); void initBMPHeader(BITMAPFILEHEADER* pBmpFileHeader) { pBmpFileHeader->bfType = 0X4D42; //Magic number pBmpFileHeader->bfSize = g_len + 320*480*3; //320*480, screen size, hardcoded. You should change it for different size pBmpFileHeader->bfReserved1 = 0X00; pBmpFileHeader->bfReserved2 = 0X00; pBmpFileHeader->bfOffBits = g_len; } void initBMPInfoHeader(BITMAPINFOHEADER* pBmpInfoHeader) { pBmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER); pBmpInfoHeader->biWidth = 320 ;//这个地方写死了,因为当时测试手机的屏幕就是这个尺寸的 pBmpInfoHeader->biHeight= 480; pBmpInfoHeader->biPlanes=1; pBmpInfoHeader->biBitCount=24; pBmpInfoHeader->biCompression=0; pBmpInfoHeader->biSizeImage=320*480*3; pBmpInfoHeader->biXPelsPerMeter = pBmpInfoHeader->biYPelsPerMeter = 0; pBmpInfoHeader->biClrUsed = pBmpInfoHeader->biClrImportant = 0; } void convetBmp(int fs,int fd, short* pSrcShortBuffer,char *pDstIntBUffer); int main(int argc,char* argv[]) { if(argc < 3) { printf("error use bmpgenerator,we need the source path"); return -1; } BITMAPFILEHEADER bmpFileHeader; initBMPHeader(&bmpFileHeader); BITMAPINFOHEADER bmpInfoHeader; initBMPInfoHeader(&bmpInfoHeader); paletteRGB bmpPalette; memset(&bmpPalette,0,sizeof(paletteRGB)); int fd = open(argv[1],O_CREAT|O_WRONLY); if(fd == -1) { printf("fail to create dst file %s\n",argv[1]); exit(-1); } int fs = open(argv[2],O_RDONLY); if(fs == -1) { printf("fail to open src file %s\n",argv[2]); exit(-1); } //Write head info to the destination file //注意:转换后BMP的数据格式是RGB888,所以不需要palette信息。关于BMP的信息可以搜索一下 write(fd,&bmpFileHeader,sizeof(BITMAPFILEHEADER)); write(fd,&bmpInfoHeader,sizeof(BITMAPINFOHEADER)); //write(fd,&bmpPalette,sizeof(paletteRGB)); //320*480 //按行来算 char* pDstIntBUffer = new char[3*320]; memset(pDstIntBUffer,0,sizeof(char)*320); short* pSrcShortBuffer = new short[320]; memset(pSrcShortBuffer,0,sizeof(short)*320); convetBmp(fs,fd,pSrcShortBuffer,pDstIntBUffer); close(fd); close(fs); delete[] pSrcShortBuffer; delete[] pDstIntBUffer; printf("bmp generated\n"); return 0; } void convetBmp(int fs,int fd, short* pSrcShortBuffer,char *pDstIntBUffer) { int height = 480; int srcLineLength = sizeof(short)*320; int dstLienLength = sizeof(char)*3*320; while(height > 0) { lseek(fs,(height-1)*srcLineLength,SEEK_SET); read(fs,(char*)pSrcShortBuffer,srcLineLength); for(int x = 0; x < 320; x++) { short srcPixel = *(pSrcShortBuffer+x); //first change RGB565 to RGB888 char srcR = (srcPixel&0xF800)>>11; char srcG = (srcPixel&0x07E0)>>5; char srcB = srcPixel&0x001F; pDstIntBUffer[x*3 + 0] = srcB; pDstIntBUffer[x*3 + 1] = srcG; pDstIntBUffer[x*3 + 2] = srcR; pDstIntBUffer[x*3 + 0] <<= 3; pDstIntBUffer[x*3 + 1] <<= 2; pDstIntBUffer[x*3 + 2] <<= 3; // pDstIntBUffer[x*3 + 0] |= (srcB&0X07); // pDstIntBUffer[x*3 + 1] |= (srcG&0X03); // pDstIntBUffer[x*3 + 2] |= (srcR&0X07); } write(fd,(char*)pDstIntBUffer,dstLienLength); --height; } }