三、实验代码
#include <stdio.h>
#include<math.h>
#include <malloc.h>
#include<windows.h>
#include "bmp2yuv.h"
#include "stdlib.h"
#define u_int8_t unsigned __int8
#define u_int unsigned __int32
#define u_int32_t unsigned __int32
void BMP2RGB(FILE * pFile, BITMAPFILEHEADER&file_h, BITMAPINFOHEADER &info_h, unsignedchar * rgbDataOut)
{
u_int32_t w, h, width, height;
u_int Loop, i, j;
unsignedchar mask, *dataBuf, *Data;
//判断像素的实际点阵数
if(((info_h.biWidth / 8 * info_h.biBitCount) % 4) == 0)
w = info_h.biWidth;
else
w = (info_h.biWidth*info_h.biBitCount+ 31) / 32 * 4;
if((info_h.biHeight % 2) == 0)
h = info_h.biHeight;
else
h = info_h.biHeight + 1;
width = w / 8 * info_h.biBitCount;//width为实际一行的字节数
height = h;//height为列数
//开辟实际字节数量的缓冲区,读数据,一次读取一个字节
dataBuf = (unsignedchar*)malloc(width*height);
Data = (unsignedchar*)malloc(width*height);
fseek(pFile, file_h.bfOffBits, 0);
if(fread(dataBuf, 1, width*height, pFile) == 0)
{
printf("read file error!\n\n");
exit(0);
}
//倒序存放
for (i= 0; i < height; i++)
for (j= 0; j < width; j++)
{
Data[i*width + j] =dataBuf[(height - i - 1)*width + j];
}
//根据不同像素位数执行不同操作
switch(info_h.biBitCount)
{
case24:
memcpy(rgbDataOut, Data,height*width);
if(dataBuf)
free(dataBuf);
if(Data)
free(Data);
return;
case16:
if(info_h.biCompression == BI_RGB)
{
for (Loop = 0; Loop < height * width; Loop += 2)
{
*rgbDataOut= (Data[Loop] & 0x1F) << 3;
*(rgbDataOut+ 1) = ((Data[Loop] & 0xE0) >> 2) + ((Data[Loop + 1] & 0x03)<< 6);
*(rgbDataOut+ 2) = (Data[Loop + 1] & 0x7C) << 1;
rgbDataOut+= 3;
}
}
/*当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,
中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,
最高的一位保留,设为0。这种格式也被称作555 16位位图。*/
if(dataBuf)
free(dataBuf);
if(Data)
free(Data);
return;
default:
RGBQUAD *pRGB = (RGBQUAD*)malloc(sizeof(RGBQUAD)*(unsigned long long)pow(float(2),info_h.biBitCount));
if(!MakePalette(pFile, file_h, info_h, pRGB))
printf("No palette!");
for(Loop = 0; Loop<height*width; Loop++)
{
switch (info_h.biBitCount)
{
case 1:
mask =0x80;
break;
case 2:
mask =0xC0;
break;
case 4:
mask =0xF0;
break;
case 8:
mask =0xFF;
}
int shiftCnt = 1;
while (mask)
{
unsignedchar index = mask == 0xFF ? Data[Loop] :((Data[Loop] & mask) >> (8 - shiftCnt * info_h.biBitCount));
*rgbDataOut= pRGB[index].rgbBlue;
*(rgbDataOut+ 1) = pRGB[index].rgbGreen;
*(rgbDataOut+ 2) = pRGB[index].rgbRed;
if (info_h.biBitCount == 8)
mask= 0;
else
mask>>= info_h.biBitCount;
rgbDataOut+= 3;
shiftCnt++;
}
}
if(dataBuf)
free(dataBuf);
if(Data)
free(Data);
if(pRGB)
free(pRGB);
return;
}
}
bool MakePalette(FILE * pFile, BITMAPFILEHEADER&file_h, BITMAPINFOHEADER & info_h, RGBQUAD *pRGB_out)
{
if((file_h.bfOffBits - sizeof(BITMAPFILEHEADER)-info_h.biSize)== sizeof(RGBQUAD)*pow(float(2),info_h.biBitCount))
{
//fseek(pFile,file_h.bfOffBits - (unsigned int)pow(float(2), info_h.biBitCount), 0);
fseek(pFile, sizeof(BITMAPFILEHEADER)+info_h.biSize, 0);
fread(pRGB_out, sizeof(RGBQUAD), (unsignedint)pow(float(2),info_h.biBitCount), pFile);
returntrue;
}
else
returnfalse;
}
四、实验结果