//====================================================
// bmp.h头文件
//====================================================
#ifndef __BMAPPARSER_H__
#define __BMAPPARSER_H__
#include "nvtfat.h"
#include "wbtypes.h"
typedef struct BMP_FILE_HEADER_S
{
unsigned short bfType; //UNIT bfType;
unsigned int bfSize; //DWORD bfSize;
unsigned short bfReserved1; //UINT bfReserved1;
unsigned short bfReserved2; //UINT bfReserved2;
unsigned int bfOffBits; //DWORD bfOffBits;
}BMP_FILE_HEADER;
typedef struct BMP_INFO_HEADER_S
{
unsigned int biSize ; // DWORD biSize;
unsigned int biWidth; // LONG biWidth;
unsigned int biHeight; // LONG biHeight;
unsigned short biPlanes; // WORD biPlanes;
unsigned short biBitCount; // WORD biBitCount;
unsigned int biCompression; // DWORD biCompression;
unsigned int biSizeImage; // DWORD biSizeImage;
unsigned int biXPelsPerMerer; // LONG biXPelsPerMerer;//水平分辨率
unsigned int biYPelsPerMerer; // LONG biYPelsPerMerer;//垂直分辨率
unsigned int biClrUsed; // DWORD biClrUsed;
unsigned int biClrImportant; // DWORD biClrImportant;
}BMP_INFO_HEADER;
typedef struct BMP_KEY_PARA_S
{
unsigned int biSize ;
unsigned int width;
unsigned int height;
unsigned short biBitCount;
unsigned int *buf;
}BMP_KEY_PARA;
typedef struct FRAME_BUF_S
{
unsigned int width;
unsigned int height;
unsigned int *buf;
// UINT8 open_flag;
}FRAME_BUF;
#define ERR_IMAGE_NULL 0
#define ERR_IMAGE_READ 1
#define ERR_IMAGE_FORMAT 2
#define ERR_IMAGE_MALLOC_FAIL 3
#define ERR_IMAGE_SIZE_MATCH 4
#define ERR_IMAGE_NOT_SUPPORT 5
void bmpFileTest(int hFile);
void bmpHeaderPartLength(int hFile);
void BmpWidthHeight(int hFile);//获取BMP文件
void bmpFileHeader(int hFile);//获取BMP文件头信息
void bmpInfoHeader(int hFile);//获取BMP文件图像信息
void getbmpFileHeader(int hFile,BMP_FILE_HEADER *file_head);
void getbmpInfoHeader(int hFile ,BMP_INFO_HEADER *bmp_info);
INT32 getbmpData(int hFile, FRAME_BUF *frameBuf);//将BMP文件数据 取出放到 frameBuf 中
UINT8 Save_bmp_file( int fd, BMP_KEY_PARA bmpData);
#endif
//========================================================================================================
//bmp.c
//========================================================================================================
/* File name: bmpTest.c
Author: wenson
Date: 2016-07-18
Description: Show all Info a bmp file has. including
FileHeader Info, InfoHeader Info and Data Part.
*/
#include "Bmp.h"
#include "wblib.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//#include "config.h"
#define BITMAPFILEHEADERLENGTH 14 // The bmp FileHeader length is 14
#define BM 19778 // The ASCII code for BM
unsigned int OffSet = 0; // OffSet from Header part to Data Part
long BmpWidth = 0; // The Width of the Data Part
long BmpHeight = 0; // The Height of the Data Part
/* Test the file is bmp file or not */
void bmpFileTest(int hFile)
{
unsigned short bfType = 0;
int rnByte = 0; //实际读出的数据长度
fsFileSeek(hFile, 0L, SEEK_SET);
// fsReadFile(&bfType, sizeof(char), 2, fpbmp);
fsReadFile(hFile, (UINT8 *)&bfType ,sizeof(bfType), &rnByte);
if (BM != bfType)
{
sysprintf("This file is not bmp file.!!!\n");
}
}
/* To get the OffSet of header to data part */
void bmpHeaderPartLength(int hFile)
{
int rnByte = 0;
fsFileSeek(hFile, 10L, SEEK_SET);
fsReadFile(hFile, (UINT8 *)&OffSet, 4, &rnByte);
//sysprintf("The Header Part is of length %d.\n", OffSet);
}
/* To get the width and height of the bmp file */
void BmpWidthHeight(int hFile)
{
int rnByte = 0;
fsFileSeek(hFile, 18L, SEEK_SET);
fsReadFile(hFile, (UINT8 *)&BmpWidth ,sizeof(BmpWidth), &rnByte);
fsReadFile(hFile, (UINT8 *)&BmpHeight ,sizeof(BmpHeight), &rnByte);
}
void getbmpFileHeader(int hFile,BMP_FILE_HEADER *file_head)//14 BYTE
{
int rnByte;
unsigned short bfType = 0; //UNIT bfType;
unsigned int bfSize = 0; //DWORD bfSize;
unsigned short bfReserved1 = 0; //UINT bfReserved1;
unsigned short bfReserved2 = 0; //UINT bfReserved2;
unsigned int bfOffBits = 0; //DWORD bfOffBits;
fsFileSeek(hFile, 0L, SEEK_SET);
fsReadFile(hFile, (UINT8 *)&bfType ,2, &rnByte);
fsReadFile(hFile, (UINT8 *)&bfSize ,4, &rnByte);
fsReadFile(hFile, (UINT8 *)&bfReserved1 ,2, &rnByte);
fsReadFile(hFile, (UINT8 *)&bfReserved2 ,2, &rnByte);
fsReadFile(hFile, (UINT8 *)&bfOffBits ,4, &rnByte);
file_head->bfType = bfType;
file_head->bfSize = bfSize;
file_head->bfReserved1 = 0;
file_head->bfReserved1 = 0;
file_head->bfOffBits = bfOffBits;
#if 0
sysprintf("************************************************\n");
sysprintf("*************tagBITMAPFILEHEADER info***********\n");
sysprintf("************************************************\n");
sysprintf("bfType is %d.\n", bfType);
sysprintf("pic file Size is %d.\n", bfSize);
sysprintf("bfReserved1 is %d.\n", bfReserved1);
sysprintf("bfReserved2 is %d.\n", bfReserved2);
sysprintf("bfOffBits is %d.\n", bfOffBits);
#endif
}
/* get tagBITMAPINFOHEADER info */
void getbmpInfoHeader(int hFile ,BMP_INFO_HEADER *bmp_info)
{
int rnByte;
unsigned int biSize = 0; // DWORD biSize;
unsigned short biWidth = 0; // LONG biWidth;
unsigned short biHeight=0; // LONG biHeight;
unsigned int biPlanes=0; // WORD biPlanes;
unsigned int biBitCount=0; // WORD biBitCount;
unsigned int biCompression=0; // DWORD biCompression;
unsigned int biSizeImage=0; // DWORD biSizeImage;
unsigned int biXPelsPerMerer=0; // LONG biXPelsPerMerer;//水平分辨率
unsigned int biYPelsPerMerer=0; // LONG biYPelsPerMerer;//垂直分辨率
unsigned int biClrUsed=0; // DWORD biClrUsed;
unsigned int biClrImportant=0; // DWORD biClrImportant;
fsFileSeek(hFile, 14L, SEEK_SET);
fsReadFile(hFile,(UINT8 *)&biSize, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biWidth, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biHeight, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biPlanes, 2, &rnByte);
fsReadFile(hFile,(UINT8 *)&biBitCount,2, &rnByte);
fsReadFile(hFile,(UINT8 *)&biCompression, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biSizeImage, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biXPelsPerMerer, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biYPelsPerMerer, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biClrUsed, 4, &rnByte);
fsReadFile(hFile,(UINT8 *)&biClrImportant, 4, &rnByte);
bmp_info->biSize = biSize;//bmpInfoHeader size
bmp_info->biWidth = biWidth;
bmp_info->biHeight = biHeight;
bmp_info->biBitCount = biBitCount;
bmp_info->biCompression = biCompression;
bmp_info->biSizeImage = biSizeImage;
bmp_info->biXPelsPerMerer = biXPelsPerMerer;
bmp_info->biYPelsPerMerer = biYPelsPerMerer;
bmp_info->biClrUsed = biClrUsed;
bmp_info->biClrImportant = biClrImportant;
#if 0
sysprintf("************************************************\n");
sysprintf("*************tagBITMAPINFOHEADER info***********\n");
sysprintf("************************************************\n");
sysprintf("biSize is %d. \n", biSize);
sysprintf("biWidth is %d.\n", biWidth);
sysprintf("biHeight is %d.\n\n", biHeight);
sysprintf("biPlanes is %d. \n", biPlanes);
sysprintf("biBitCount is %d. \n", biBitCount);
sysprintf("biCompression is %d. \n", biCompression);
sysprintf("biSizeImage is %d Bytes. \n", biSizeImage);
sysprintf("biXPelsPerMerer is %d.\n", biXPelsPerMerer);
sysprintf("biYPelsPerMerer is %d.\n", biYPelsPerMerer);
sysprintf("biClrUsed is %d. \n", biClrUsed);
sysprintf("biClrImportant is %d. \n", biClrImportant);
#endif
}
/*
function: getdata from *.bmp
input:file handle ,read data storage buf
output: no output
return: no return
*/
unsigned int getBmpDataSize(int fd)
{
int rnByte = 0;
unsigned int size = 0;
fsFileSeek(fd, 34L, SEEK_SET);
fsReadFile(fd,(unsigned char *)&size, 4, &rnByte);
return size;
}
/*
* 将888数据 转为565数据
*/
void rgb888_to_rgb565(const void * psrc, int w, int h, void * pdst)
{
int srclinesize = (w * 3);
int dstlinesize = (w * 2);
const unsigned char * psrcline;
const unsigned char * psrcdot;
unsigned char * pdstline;
unsigned short * pdstdot;
int i,j;
if (!psrc || !pdst || w <= 0 || h <= 0)
{
sysprintf("rgb888_to_rgb565 : parameter error\n");
return;
}
psrcline = (const unsigned char *)psrc;
pdstline = (unsigned char *)pdst;
for (i=0; i<h; i++) {
psrcdot = psrcline;
pdstdot = (unsigned short *)pdstline;
for (j=0; j<w; j++) {
//888 r|g|b -> 565 b|g|r
*pdstdot = ((psrcdot[2] & 0xF8) << 8)//r
|((psrcdot[1] & 0xFC) << 3)//g
| (psrcdot[0] >> 3);//b
psrcdot += 3;
pdstdot++;
}
psrcline += srclinesize;
pdstline += dstlinesize;
}
return ;
}
//get data from bmp file to point buf
INT32 getbmpData(int hFile, FRAME_BUF *frameBuf)
{
int i;
int result;
int rnByte;
UINT8 *sourceBuf = NULL,*targetBuf = NULL;
unsigned int bmpdatalen = 0;
BMP_FILE_HEADER bmpFileHeadr;
BMP_INFO_HEADER bmpInfoHeadr;
getbmpFileHeader(hFile,(BMP_FILE_HEADER *)&bmpFileHeadr);
getbmpInfoHeader(hFile,(BMP_INFO_HEADER *)&bmpInfoHeadr);
//check BMP type
if (BM != bmpFileHeadr.bfType)
{
sysprintf("the pic is not bmp format!!!\n");
return ERR_IMAGE_FORMAT;
}
if(( bmpInfoHeadr.biBitCount != 24)&&( bmpInfoHeadr.biBitCount != 16))
{
sysprintf(" not support the %d bits bmp\n",bmpInfoHeadr.biBitCount);
return ERR_IMAGE_NOT_SUPPORT;
}
if((bmpInfoHeadr.biHeight != frameBuf->height)||(bmpInfoHeadr.biWidth != frameBuf->width))
{
sysprintf(" frame buf size not match pic !!!!\n");
return ERR_IMAGE_SIZE_MATCH;
}
fsFileSeek(hFile, bmpFileHeadr.bfOffBits, SEEK_SET);
bmpdatalen = bmpInfoHeadr.biWidth * bmpInfoHeadr.biBitCount / 8;
sourceBuf = (UINT8 *)malloc(bmpdatalen);
if(sourceBuf == NULL){
sysprintf("malloc pic tempbuf fail!!!\n");
return ERR_IMAGE_MALLOC_FAIL;
}
targetBuf = (UINT8 *)frameBuf->buf + (frameBuf->height - 1) * frameBuf->width * 2;
for(i = 0 ; i < bmpInfoHeadr.biHeight ; i++){
result = fsReadFile(hFile,sourceBuf ,(bmpdatalen), &rnByte);
if(result != FS_OK)
{
sysprintf("fs read error!!!\n");
free(sourceBuf);
return ERR_IMAGE_READ;
}
if(bmpInfoHeadr.biBitCount == 24)
{
rgb888_to_rgb565(sourceBuf,(bmpInfoHeadr.biWidth),1,sourceBuf);
}
memcpy(targetBuf,sourceBuf,frameBuf->width * 2);
targetBuf -= ( frameBuf->width * 2 );
}
free(sourceBuf);
return ERR_IMAGE_NULL;
}
UINT8 Save_bmp_file( int fd, BMP_KEY_PARA bmpData)
{
int i;
int wnByte = 0; //实际写入的数据长度
BMP_FILE_HEADER g_bmpFileHeadr;
BMP_INFO_HEADER g_bmpInfoHeadr;
UINT8 *pbuf = NULL,*temp_buf = NULL;
UINT32 data_len;
UINT8 aline4_offset = 0;
if(fd < 0)
{
sysprintf("save fd error!!!\n");
return 1;
}
else
{
sysprintf("save fd start!!!\n");
}
data_len = bmpData.width * bmpData.height * bmpData.biBitCount / 8;
aline4_offset = ((data_len+54) % 4);
if(aline4_offset)
{
aline4_offset = 4 - aline4_offset;
data_len += (4 - aline4_offset);
}
//位图文件头
g_bmpFileHeadr.bfType = BM;
g_bmpFileHeadr.bfSize = data_len+54;
g_bmpFileHeadr.bfReserved1 = 0x0000;
g_bmpFileHeadr.bfReserved2 = 0x0000;
g_bmpFileHeadr.bfOffBits = 54;
//位图信息头格式定义
g_bmpInfoHeadr.biSize = 40;
g_bmpInfoHeadr.biWidth = bmpData.width;
g_bmpInfoHeadr.biHeight = bmpData.height;
g_bmpInfoHeadr.biPlanes = 1;
g_bmpInfoHeadr.biBitCount = bmpData.biBitCount;
g_bmpInfoHeadr.biCompression = 0;
g_bmpInfoHeadr.biSizeImage = data_len; //位图阵列表字节数
g_bmpInfoHeadr.biXPelsPerMerer = 0;//水平分辨率
g_bmpInfoHeadr.biYPelsPerMerer = 0; //垂直分辨率
g_bmpInfoHeadr.biClrUsed = 0; //位图实际使用的颜色表中的颜色变址数
g_bmpInfoHeadr.biClrImportant = 0; //位图显示过程中被认为重要颜色变址数
data_len = bmpData.width * bmpData.biBitCount / 8;
temp_buf = (unsigned char *)malloc(data_len);
if(temp_buf <= 0)
{
sysprintf("save malloc buf fail....\n");
return 1;
}
fsFileSeek(fd,0,SEEK_SET);
fsWriteFile(fd, (UINT8 *)&g_bmpFileHeadr.bfType, 2, &wnByte);
fsWriteFile(fd, (UINT8 *)&g_bmpFileHeadr.bfSize, 12, &wnByte);
fsWriteFile(fd, (UINT8 *)&g_bmpInfoHeadr, 40, &wnByte);
pbuf = (UINT8 *)bmpData.buf + (bmpData.height - 1) * data_len;
for( i = 0 ;i < bmpData.height ; i++)
{
memcpy(temp_buf, pbuf,data_len);
fsWriteFile(fd,temp_buf, data_len, &wnByte);
pbuf -= data_len;
}
memset(temp_buf,0x0,4);
if(aline4_offset > 0)
{
sysprintf(" aline4_offset %d ....\n",aline4_offset);
fsWriteFile(fd,temp_buf, aline4_offset, &wnByte);
}
free(temp_buf);
temp_buf = NULL;
return 0;
}