/*只适用于WINDOWS BMP格式 真彩*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BMPFILETYPE (0x4D42)
#pragma pack(push,2)
/**
***定义文件头14字节.以2字节对齐
**/
typedef struct _tagBMPFILE
{
unsigned short int bfType; //文件类型恒为"BM"==0x4D42
unsigned int bfSize; //文件大小,包括本结构
unsigned short int bfReserved1; //保留位1
unsigned short int bfReserved2; //保留位2
unsigned int bfOffsetBits; //到像素矩阵的偏移.
}BMPFILE,*LPBMPFILE;
/**
***定义信息头40字节.以2字节对齐
**/
typedef struct _tagBMPINFOHEADER
{
unsigned int biSize; //本结构大小 恒为40字节
int biWidth; //DIB宽度 像素为单位
int biHeight; //DIB高度 像素为单位
unsigned short int biPlanes; //不用理会..恒为1
unsigned short int biBitCount; //颜色深度
unsigned int biCompression; //是否压缩
unsigned int biSizeImage; //DIB总大小 每行四字节对齐后算的
int biXPelsPerMeter; //水平分辨率 像素每米
int biYPelsPerMeter; //竖直分辨率 像素每米
unsigned int biClrUsed; //已用颜色数
unsigned int biClrImportant; //重要颜色数
}BMPINFOHEADER,*LPBMPINFOHEADER;
#pragma pack(pop)
typedef void * LPDIB;
//用于补齐行边界.返回的是字节数 4的整数倍
#define ROWWIDTH(bits) ((((bits)+31)&~31)>>3)
int xxx(const char *fName, const char *fOut1, const char *fOut2)
{
int i;
FILE *fp;
FILE *pic1, *pic2;
int h1, h2;
int nRowPix;
int nRowWidth;
BMPFILE l_bmpFile;
BMPINFOHEADER l_bmpInfo;
unsigned char *buff;
if (fName == NULL || strlen(fName) == 0)
{
return -1;
}
if ((fp = fopen(fName, "rb")) == NULL)
{
perror("fopen");
return -1;
}
memset(&l_bmpFile, 0, sizeof(BMPFILE));
if (fread(&l_bmpFile, sizeof(BMPFILE), 1, fp) < 1)
{
perror("fread");
goto err_exit;
}
if (l_bmpFile.bfType != BMPFILETYPE)
{
fprintf(stderr, "Not a bitmap file!\n");
goto err_exit;
}
if (fread(&l_bmpInfo, sizeof(BMPINFOHEADER), 1, fp) < 1)
{
perror("fread");
goto err_exit;
}
nRowPix = l_bmpInfo.biWidth * l_bmpInfo.biBitCount;
nRowWidth = ROWWIDTH(nRowPix);
if ((buff = (unsigned char *)malloc(nRowWidth)) == NULL)
{
goto err_exit;
}
h1 = l_bmpInfo.biHeight / 2;
h2 = l_bmpInfo.biHeight - h1;
/*下面不管错误了,文件很麻烦..上面代码都有.*/
pic1 = fopen(fOut1, "wb");
pic2 = fopen(fOut2, "wb");
l_bmpFile.bfSize = sizeof(BMPFILE) + sizeof(BMPINFOHEADER) + h1 * nRowWidth;
fwrite(&l_bmpFile, sizeof(BMPFILE), 1, pic1);
l_bmpInfo.biHeight = h1;
l_bmpInfo.biSizeImage = nRowWidth * h1;
fwrite(&l_bmpInfo, sizeof(BMPINFOHEADER), 1, pic1);
for (i = 0; i < h1; i ++)
{
fread(buff, nRowWidth, 1, fp);
fwrite(buff, nRowWidth, 1, pic1);
}
fclose(pic1);
l_bmpFile.bfSize = sizeof(BMPFILE) + sizeof(BMPINFOHEADER) + h2 * nRowWidth;
fwrite(&l_bmpFile, sizeof(BMPFILE), 1, pic2);
l_bmpInfo.biHeight = h2;
l_bmpInfo.biSizeImage = nRowWidth * h2;
fwrite(&l_bmpInfo, sizeof(BMPINFOHEADER), 1, pic2);
for (i = 0; i < h2; i ++)
{
fread(buff, nRowWidth, 1, fp);
fwrite(buff, nRowWidth, 1, pic2);
}
fclose(pic1);
free(buff);
fclose(fp);
return 0;
err_exit:
fclose(fp);
return -1;
}
int main()
{
xxx("test.bmp", "2.bmp", "1.bmp");
return 0;
}