/*************************************************************************************************************************
* 函数 : BMP_ERROR BMP_FullDecode(u8 *InBmpFileBuff, u32 InBmpFileSize, u8 *pOutRGB_DataBuff, u32 OutRGB_DataBuffSize, BMP_COLOR_MODE OutRGB_ColorMode, BMP_INFO *pOutBmpInfo)
* 功能 : BMP图片软解析(全部解析)
* 参数 : InBmpFileBuff:输入的图片文件缓冲区;InBmpFileSize:输入的图片文件大小;pOutRGB_DataBuff:输出的RGB数据缓冲区;OutRGB_DataBuffSize:输出的RGB数据缓冲区大小;
OutRGB_ColorMode:输出RGB像素格式,支持RGB565,RGB888,ARGB8888;pOutBmpInfo:解析后的图片基本信息
* 返回 : BMP_ERROR
* 依赖 : 底层
* 作者 : cp1300@139.com
* 时间 : 2011-09-19
* 最后修改时间 : 2020-02-06
* 说明 : 无
*************************************************************************************************************************/
BMP_ERROR BMP_FullDecode(u8 *InBmpFileBuff, u32 InBmpFileSize, u8 *pOutRGB_DataBuff, u32 OutRGB_DataBuffSize, BMP_COLOR_MODE OutRGB_ColorMode, BMP_INFO *pOutBmpInfo)
{
BMP_FILE_HEADER *pBmpHeader; //图片文件头
BMP_FullDecodeDataType mDecodeTempData; //图片解析所需的临时变量
BMP_ERROR mBmpError = BMP_OK; //图片解析状态
u32 temp;
//基本数据初始化
pBmpHeader = (BMP_FILE_HEADER*)InBmpFileBuff; //得到BMP的头部信息
mDecodeTempData.mBmpInfo.bfOffBits = pBmpHeader->bfOffBits; //位图数据偏移地址偏移
mDecodeTempData.mBmpInfo.biBitCount = pBmpHeader->biBitCount; //位图数据的颜色深度只支持16bit,24bit,32bit
mDecodeTempData.mBmpInfo.biWidth = pBmpHeader->biWidth; //位图的水平像素数
mDecodeTempData.mBmpInfo.biHeight = pBmpHeader->biHeight; //位图的垂直像素数
mDecodeTempData.mBmpInfo.biSizeImage = pBmpHeader->biSizeImage; //位图的数据大小
mDecodeTempData.OutPixelOffset = 0; //数据输出偏移,像素偏移-用于16bit与32bit图片的索引,效率会比字节偏移高
mDecodeTempData.OutByteOffset = 0; //数据输出偏移,字节偏移,用于24bit格式图片下的偏移计算
mDecodeTempData.OutRGB_ColorMode = OutRGB_ColorMode; //输出像素格式
mDecodeTempData.InBmpFileSize = InBmpFileSize; //输入的图片数据文件大小
/****************************************************/
//调试
printf("\r\n地址偏移:%d\r\n", mDecodeTempData.mBmpInfo.bfOffBits);
printf("颜色深度:%d\r\n", mDecodeTempData.mBmpInfo.biBitCount);
printf("水平分辨率:%d\r\n", mDecodeTempData.mBmpInfo.biWidth);
printf("垂直分辨率:%d\r\n", mDecodeTempData.mBmpInfo.biHeight);
printf("数据大小:%luB\r\n", mDecodeTempData.mBmpInfo.biSizeImage);
printf("位图标志:0x%04X\r\n", pBmpHeader->bfType);
printf("位图biCompression:0x%lx\r\n\r\n", pBmpHeader->biCompression);
/*****************************************************/
//水平像素必须是4的倍数!!
if((mDecodeTempData.mBmpInfo.biWidth * mDecodeTempData.mBmpInfo.biBitCount / 8) % 4) //水平像素字节数不是4的整数倍
mDecodeTempData.uiTemp = ((mDecodeTempData.mBmpInfo.biWidth * mDecodeTempData.mBmpInfo.biBitCount / 8) / 4 + 1) * 4; //将水平像素字节数扩展成4的整数倍
else
mDecodeTempData.uiTemp = mDecodeTempData.mBmpInfo.biWidth * mDecodeTempData.mBmpInfo.biBitCount / 8;
mDecodeTempData.xValid = mDecodeTempData.mBmpInfo.biWidth * (mDecodeTempData.mBmpInfo.biBitCount / 8); //计算水平有效地数据字节数
//判断是否是合法的头信息
if(pBmpHeader->bfType != 0x4d42)//BM,BMP文件的头信息
{
mBmpError = BMP_ILLEGAL_ERROR;
DEBUG("非法的BMP图片,没有找到BMP图片头信息\r\n");
goto end_loop;
}
if(pBmpHeader->biCompression) //判断BMP图像是否是压缩的,如果是压缩的将不支持
{
mBmpError = BMP_COMP_ERROR;
DEBUG("不支持压缩的BMP图片\r\n");
goto end_loop;
}
BMP_memcpy((u8 *)pOutBmpInfo, (u8 *)&mDecodeTempData.mBmpInfo, sizeof(BMP_INFO)); //拷贝图片信息
mDecodeTempData.y = mDecodeTempData.mBmpInfo.biHeight - 1; //BMP图片由左下角到右上角刷新,因此起点y坐标要加上图片的高度
mDecodeTempData.x = 0;
mDecodeTempData.xEnd = 0 + mDecodeTempData.mBmpInfo.biWidth; //x终点坐标
//输入指针初始化
mDecodeTempData.FileOffset = mDecodeTempData.mBmpInfo.bfOffBits; //文件偏移
mDecodeTempData.InData32bit = (u32 *)&InBmpFileBuff[mDecodeTempData.FileOffset]; //跳到图片数据区
mDecodeTempData.InData16bit = (u16 *)&InBmpFileBuff[mDecodeTempData.FileOffset]; //跳到图片数据区
mDecodeTempData.InData24bit = (BMP_RGB_24BIT *)&InBmpFileBuff[mDecodeTempData.FileOffset]; //跳到图片数据区
//输出指针初始化
mDecodeTempData.OutData32bit = (u32 *)pOutRGB_DataBuff; //临时指针,用于输出32BIT的RGB数据-指向输出RGB缓冲区
mDecodeTempData.OutData16bit = (u16 *)pOutRGB_DataBuff; //临时指针,用于输出16BIT的RGB数据-指向输出RGB缓冲区
mDecodeTempData.OutData24bit = (BMP_RGB_24BIT *)pOutRGB_DataBuff; //临时指针,用于输出16BIT的RGB数据-指向输出RGB缓冲区
switch(OutRGB_ColorMode) //输出像素数据格式
{
case BMP_COLOR_ARGB8888 : //32bit格式输出
{
mDecodeTempData.OutPixelByte = 4; //4字节
}break;
case BMP_COLOR_RGB888 : //24bit格式输出
{
mDecodeTempData.OutPixelByte = 3; //3字节
}break;
default: //默认为RGB555
{
mDecodeTempData.OutPixelByte = 2; //2字节
}break;
}
mDecodeTempData.OutPixelOffset = mDecodeTempData.y * mDecodeTempData.mBmpInfo.biWidth + mDecodeTempData.x; //计算偏移位置,从最下角开始
temp = (u32)mDecodeTempData.mBmpInfo.biWidth * mDecodeTempData.mBmpInfo.biHeight * mDecodeTempData.OutPixelByte; //计算需要的输出缓冲区大小
if(OutRGB_DataBuffSize < temp)
{
DEBUG("解析BMP图片出错,输出缓冲区(%luB)过小,至少需要%luB\r\n", OutRGB_DataBuffSize, temp);
}
switch (mDecodeTempData.mBmpInfo.biBitCount)//判断图片颜色深度
{
case 32: //32BIT ARGB8888
{
mBmpError = BMP_FullDecode32bit_Module(&mDecodeTempData); //子流程-32bit位图完全解析(从内存中读取图片数据,然后解析到内存中)
}break;
case 24: //24BIT RGB888 //可能存在4字节对齐问题
{
mBmpError = BMP_FullDecode24bit_Module(&mDecodeTempData); //调用子流程,解析24bit数据
}break;
case 16: //16BIT RGB555
{
mBmpError = BMP_FullDecode16bit_Module(&mDecodeTempData); //子流程-16it位图完全解析(从内存中读取图片数据,然后解析到内存中)
}break;
default : break;//只支持16BIT,24BIT,32BIT图片的解码
}
end_loop:
return mBmpError;
}
|