修改bitmap 头文件,使其符合标准C ,适用于跨平台开发
bitmap.h
#ifndef _BMP_HEADER_DEF_H_
#define _BMP_HEADER_DEF_H_
#pragma pack(push,1)
typedef int LONG;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned char BYTE;
typedef struct tagBITMAPFILEHEADER{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
}BITMAPFILEHEADER,*PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
}BITMAPINFOHEADER,*PBITMAPINFOHEADER;
typedef struct tagRGBQUAD{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
}RGBQUAD;
#pragma pack(pop)
#endif
存取8bit BMP图像实现
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "bitmap.h"
int write_bmp(const char *path ,BYTE * data,int w,int h)
{
FILE *fd=fopen(path,"wb+");
int ret=0,len,i;
len=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256+w*h;
BYTE *image=(BYTE *)malloc(len);
BITMAPFILEHEADER *pfh=(BITMAPFILEHEADER *)image;
BITMAPINFOHEADER *pinfo=(BITMAPINFOHEADER *)(image+sizeof(BITMAPFILEHEADER));
RGBQUAD *rgb=(RGBQUAD*)(image+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
pfh->bfType=0x4d42;
pfh->bfSize=len;
pfh->bfReserved1=pfh->bfReserved2=0;
pfh->bfOffBits=len-w*h;
pinfo->biSize=sizeof(BITMAPINFOHEADER);
pinfo->biWidth=w;
pinfo->biHeight=h;
pinfo->biPlanes=1;
pinfo->biBitCount=8;
pinfo->biCompression=0;
pinfo->biSizeImage=w*h;
pinfo->biXPelsPerMeter=3780;
pinfo->biYPelsPerMeter=3780;
pinfo->biClrUsed=256;
pinfo->biClrImportant=0;
for(i=0;i<256;i++){
rgb[i].rgbBlue=i;
rgb[i].rgbGreen=i;
rgb[i].rgbRed=i;
rgb[i].rgbReserved=0;
}
memcpy(image+pfh->bfOffBits,data,w*h);
if(!fd){
perror(path);
exit(EXIT_FAILURE);
}
ret=fwrite(image,1,len,fd);
if(ret!=len){
perror(path);
exit(EXIT_FAILURE);
}
fclose(fd);
free(image);
return ret;
}
unsigned char * load_bmp(const char *path, int *w,int *h)
{
FILE *fd;
struct stat sb;
unsigned char *buffer,*pbuff;
size_t size,n;
fd=fopen(path,"rb");
if(!fd){
perror(path);
exit(EXIT_FAILURE);
}
if(stat(path,&sb)){
perror(path);
exit(EXIT_FAILURE);
}
size=sb.st_size;
buffer=malloc(size);
if(!buffer){
fprintf(stderr, "Unable to allocate %lld bytes\n",(long long)size);
exit(EXIT_FAILURE);
}
n=fread(buffer,1,size,fd);
if(n!=size){
perror(path);
exit(EXIT_FAILURE);
}
fclose(fd);
BITMAPFILEHEADER *pfh=(BITMAPFILEHEADER *)buffer;
assert(sizeof(BITMAPFILEHEADER)==14);
//printf("the struct BITMAPFILEHEADER len!=14,please change mem alignment,like this #pragma pack(1)\n") ;
if(pfh->bfType!=0x4d42)return NULL;
BITMAPINFOHEADER *pinfo=(BITMAPINFOHEADER*)(buffer+sizeof(BITMAPFILEHEADER));
*w=pinfo->biWidth;
*h=pinfo->biHeight;
//printf("load_file heilght=%d,%d\n",pinfo->biWidth*pinfo->biHeight,1);
pbuff=malloc(pinfo->biWidth*pinfo->biHeight);
memcpy(pbuff,buffer+pfh->bfOffBits,pinfo->biWidth*pinfo->biHeight);
#if 0
printf("pfh->bfOffBits=%d\n",pfh->bfOffBits);
printf("pfh->bfSize=%d\n",pfh->bfSize);
printf("pinfo->biSize=%d\n",pinfo->biSize);
printf("pinfo->biClrImportant=%d\n",pinfo->biClrImportant);
printf("struct len=%ld\n",sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
#endif
free(buffer);
return pbuff;
}
#if 1
int main(int argc,char **argv)
{
int w,h;
unsigned char *image=load_bmp("test1.bmp",&w,&h);
printf("w=%d,h=%d\n",w,h);
write_bmp("save.bmp" ,image,w,h);
free(image);
return 0;
}
#endif