//======================================================
// 文件名称: BitMap.c
// 功能描述: 位图处理
// 维护记录: 2007-02-09 v1.0 by lijian
// 注意事项: 该程序中涉及到的数据类型需要根据平台确定
// 其中,COLOR类型为无符号16bit数据类型
// RGB()是一个宏主要完成RGB三色数据向16bit 565格式的转换,
// 该宏的完整定义如下:
// #define RGB(r, g, b) RGB24(r, g, b)
// #define RGB24(r, g, b) ( (((COLOR)r&0xf8) // #define RGB16(rgb) ( (((COLOR)rgb&0xffe0) //======================================================
#include "BitMap.h"
//=============================================================
//语法格式: UINT8 BMP_OpenFile(UINT8 *BitFile)
//实现功能: 读取位图文件信息
//参数: BFile - BMP文件指针
// BitFile - 位图文件保存首地址
//返回值: 成功返回0, 失败(不支持的格式)返回-1
//=============================================================
UINT8 BMP_OpenFile(BITMAP_FILE *BFile, UINT8 *BitFile)
{
UINT32 i;
BFile->Opened = 0;
BFile->FileHead.Type = (UINT16)BitFile[0] + ((UINT16)BitFile[1] BFile->FileHead.FileSize = (UINT32)BitFile[2] + ((UINT32)BitFile[3] BFile->FileHead.Offset = (UINT32)BitFile[0x0a] + ((UINT32)BitFile[0x0b] BFile->InfoHead.HeadSize = (UINT32)BitFile[0x0e] + ((UINT32)BitFile[0x0f] BFile->InfoHead.Width = (UINT32)BitFile[0x12] + ((UINT32)BitFile[0x13] BFile->InfoHead.Height = (UINT32)BitFile[0x16] + ((UINT32)BitFile[0x17] BFile->InfoHead.BitPerPixel = (UINT16)BitFile[0x1c] + ((UINT16)BitFile[0x1d] BFile->InfoHead.CompresType = (UINT32)BitFile[0x1e] + ((UINT32)BitFile[0x1f] BFile->InfoHead.ColorTable.CTOffset = BFile->InfoHead.HeadSize + 0x0e;
BFile->InfoHead.ColorTable.CTSize = (BFile->FileHead.Offset - BFile->InfoHead.HeadSize - 0x0e) >> 2;
BFile->InfoHead.DataSize = (UINT32)BitFile[0x22] + ((UINT32)BitFile[0x23] BFile->Data = BitFile;
BFile->LineWidth = (((BFile->InfoHead.Width * BFile->InfoHead.BitPerPixel) + 31) >> 5) if((BFile->FileHead.Type != 0x4d42) || ((BFile->InfoHead.CompresType != BI_RGB) && (BFile->InfoHead.CompresType != BI_BITFIELDS)))
// 仅支持不压缩的位图格式
{
return -1;
}
for(i = 0; i < BFile->InfoHead.ColorTable.CTSize; i++)
{
BFile->InfoHead.ColorTable.ColorTable[i].B = BitFile[BFile->InfoHead.ColorTable.CTOffset + 4 * i];
BFile->InfoHead.ColorTable.ColorTable[i].G = BitFile[BFile->InfoHead.ColorTable.CTOffset + 4 * i + 1];
BFile->InfoHead.ColorTable.ColorTable[i].R = BitFile[BFile->InfoHead.ColorTable.CTOffset + 4 * i + 2];
BFile->InfoHead.ColorTable.ColorTable[i].Filled = 0;
}
BFile->Opened = 1;
return 0;
}
//=============================================================
//语法格式: UINT8 BMP_CheckFormat(void)
//实现功能: 检查文件格式是否支持
//参数: BFile - BMP文件指针
//返回值: 支持返回1, 不支持返回0
//注意事项: 需要首先调用BMP_OpenFile()函数读取文件信息
//=============================================================
UINT8 BMP_CheckFormat(BITMAP_FILE *BFile)
{
return BFile->Opened;
}
//=============================================================
//语法格式: UINT32 BMP_GetWidth(void)
//实现功能: 得到文件宽度
//参数: BFile - BMP文件指针
//返回值: 文件宽度
//注意事项: 需要首先调用BMP_OpenFile()函数读取文件信息
//=============================================================
UINT32 BMP_GetWidth(BITMAP_FILE *BFile)
{
if(BFile->Opened == 0)
return 0;
return(BFile->InfoHead.Width);
}
//=============================================================
//语法格式: UINT32 BMP_GetHeight(void)
//实现功能: 得到文件高度
//参数: BFile - BMP文件指针
//返回值: 文件高度
//注意事项: 需要首先调用BMP_OpenFile()函数读取文件信息
//=============================================================
UINT32 BMP_GetHeight(BITMAP_FILE *BFile)
{
if(BFile->Opened == 0)
return 0;
return(BFile->InfoHead.Height);
}
//=============================================================
//语法格式: UINT32 BMP_GetOffset(void)
//实现功能: 得到位图数据的偏移地址
//参数: BFile - BMP文件指针
//返回值: 位图数据偏移
//注意事项: 需要首先调用BMP_OpenFile()函数读取文件信息
//=============================================================
UINT32 BMP_GetOffset(BITMAP_FILE *BFile)
{
if(BFile->Opened == 0)
return 0;
return(BFile->FileHead.Offset);
}
//=============================================================
//语法格式: UINT32 BMP_GetLineWidth(void)
//实现功能: 得到每行图象占用的byte数
//参数: BFile - BMP文件指针
//返回值: 每行图象占用的byte数
//注意事项: 需要首先调用BMP_OpenFile()函数读取文件信息
//=============================================================
UINT32 BMP_GetLineWidth(BITMAP_FILE *BFile)
{
if(BFile->Opened == 0)
return 0;
return(BFile->LineWidth);
}
//=============================================================
//语法格式: UINT32 BMP_GetLineColor2(BITMAP_FILE *BFile, UINT8 *DataAddr, COLOR *ColorTable)
//实现功能: 从指定地址处获取该行的颜色
//参数: BFile - BMP文件指针
// DataAddr- 位图行数据保存首地址
// ColorTable- 保存颜色的数组
//返回值: 成功返回0, 失败(不支持的格式)返回-1
//=============================================================
UINT32 BMP_GetLineColor2(BITMAP_FILE *BFile, UINT8 *DataAddr, COLOR *ColorTable)
{
UINT32 Offset = 0;
RGBQUAD CT;
int i;
if(BFile->Opened == 0)
return 0;
// Offset = (BFile->InfoHead.Height - 1 - line) * (BFile->LineWidth FileHead.Offset * 8;
Offset = 0;
switch(BFile->InfoHead.BitPerPixel)
{
case BP_SINGLE:
for(i = 0; i < BFile->InfoHead.Width; i++)
{
if((DataAddr[Offset >> 3] & (0x80 >> ((UINT8)Offset & 0x07))) != 0)
ColorTable[i] = RGB(0xff, 0xff, 0xff);
else
ColorTable[i] = RGB(0, 0, 0);
Offset++;
}
break;
case BP_16COLOR:
for(i = 0; i < BFile->InfoHead.Width; i++)
{
if(((UINT8)Offset & 0x08))
CT = BFile->InfoHead.ColorTable.ColorTable[DataAddr[Offset >> 3] & 0x0f];
else
CT = BFile->InfoHead.ColorTable.ColorTable[(DataAddr[Offset >> 3] >> 4) & 0x0f];
ColorTable[i] = RGB(CT.R, CT.G, CT.B);
Offset += 4;
}
break;
case BP_256COLOR:
for(i = 0; i < BFile->InfoHead.Width; i++)
{
CT = BFile->InfoHead.ColorTable.ColorTable[DataAddr[Offset >> 3]];
ColorTable[i] = RGB(CT.R, CT.G, CT.B);
Offset += 8;
}
break;
case BP_16BITCOLOR:
Offset >>= 3;
for(i = 0; i < BFile->InfoHead.Width; i++)
{
ColorTable[i] = RGB16(*(UINT16 *)(DataAddr + Offset));
Offset += 2;
}
break;
case BP_24BITCOLOR:
case BP_32BITCOLOR:
Offset >>= 3;
for(i = 0; i < BFile->InfoHead.Width; i++)
{
ColorTable[i] = RGB(DataAddr[Offset + 2], DataAddr[Offset + 1], DataAddr[Offset]);
Offset += 3;
}
break;
default:
return 0;
break;
}
return BFile->InfoHead.Width;
}
//=============================================================
//语法格式: UINT32 BMP_GetLineColor(BITMAP_FILE *BFile, UINT16 line, COLOR *ColorTable)
//实现功能: 获取指定行的颜色
//参数: BFile - BMP文件指针
// line - 行数(自上而下)
// ColorTable- 保存颜色的数组
//返回值: 成功返回0, 失败(不支持的格式)返回-1
//=============================================================
UINT32 BMP_GetLineColor(BITMAP_FILE *BFile, UINT16 line, COLOR *ColorTable)
{
UINT32 Offset = 0;
RGBQUAD CT;
int i;
if(BFile->Opened == 0)
return 0;
Offset = (BFile->InfoHead.Height - 1 - line) * (BFile->LineWidth FileHead.Offset * 8;
switch(BFile->InfoHead.BitPerPixel)
{
case BP_SINGLE:
for(i = 0; i < BFile->InfoHead.Width; i++)
{
if((BFile->Data[Offset >> 3] & (0x80 >> ((UINT8)Offset & 0x07))) != 0)
ColorTable[i] = RGB(0xff, 0xff, 0xff);
else
ColorTable[i] = RGB(0, 0, 0);
Offset++;
}
break;
case BP_16COLOR:
for(i = 0; i < BFile->InfoHead.Width; i++)
{
if(((UINT8)Offset & 0x08))
CT = BFile->InfoHead.ColorTable.ColorTable[BFile->Data[Offset >> 3] & 0x0f];
else
CT = BFile->InfoHead.ColorTable.ColorTable[(BFile->Data[Offset >> 3] >> 4) & 0x0f];
ColorTable[i] = RGB(CT.R, CT.G, CT.B);
Offset += 4;
}
break;
case BP_256COLOR:
for(i = 0; i < BFile->InfoHead.Width; i++)
{
CT = BFile->InfoHead.ColorTable.ColorTable[BFile->Data[Offset >> 3]];
ColorTable[i] = RGB(CT.R, CT.G, CT.B);
Offset += 8;
}
break;
case BP_16BITCOLOR:
Offset >>= 3;
for(i = 0; i < BFile->InfoHead.Width; i++)
{
ColorTable[i] = RGB16(*(UINT16 *)(BFile->Data + Offset));
Offset += 2;
}
break;
case BP_24BITCOLOR:
case BP_32BITCOLOR:
Offset >>= 3;
for(i = 0; i < BFile->InfoHead.Width; i++)
{
ColorTable[i] = RGB(BFile->Data[Offset + 2], BFile->Data[Offset + 1], BFile->Data[Offset]);
Offset += 3;
}
break;
default:
return 0;
break;
}
return BFile->InfoHead.Width;
}
//=============================================================
//语法格式: COLOR BMP_GetPixelColor(UINT16 x, UINT16 y)
//实现功能: 得到指定点的颜色
//参数: BFile - BMP文件指针
// x - 横坐标
// y - 纵坐标
//返回值: 颜色(保存格式为16bit 565真彩格式:rrrrr-ggggg-bbbbb)
//注意事项: 需要首先调用BMP_OpenFile()函数读取文件信息
// 另外,函数中没有对坐标的有效性进行检查,使用的时候注意!
//=============================================================
COLOR BMP_GetPixelColor(BITMAP_FILE *BFile, UINT16 x, UINT16 y)
{
UINT32 Offset = 0;
COLOR Ret = RGB(0, 0, 0);
RGBQUAD CT;
if(BFile->Opened == 0)
return RGB(0, 0, 0);
Offset = (BFile->InfoHead.Height - 1 - y) * (BFile->LineWidth InfoHead.BitPerPixel + BFile->FileHead.Offset * 8;
switch(BFile->InfoHead.BitPerPixel)
{
case BP_SINGLE:
if((BFile->Data[Offset >> 3] & (0x80 >> ((UINT8)Offset & 0x07))) != 0)
Ret = RGB(0xff, 0xff, 0xff);
else
Ret = RGB(0, 0, 0);
break;
case BP_16COLOR:
if(((UINT8)Offset & 0x08))
CT = BFile->InfoHead.ColorTable.ColorTable[BFile->Data[Offset >> 3] & 0x0f];
else
CT = BFile->InfoHead.ColorTable.ColorTable[(BFile->Data[Offset >> 3] >> 4) & 0x0f];
Ret = RGB(CT.R, CT.G, CT.B);
break;
case BP_256COLOR:
CT = BFile->InfoHead.ColorTable.ColorTable[BFile->Data[Offset >> 3]];
Ret = RGB(CT.R, CT.G, CT.B);
break;
case BP_16BITCOLOR:
Ret = RGB16(*(UINT16 *)(BFile->Data + (Offset >> 3)));
break;
case BP_24BITCOLOR:
case BP_32BITCOLOR:
Offset >>= 3;
Ret = RGB(BFile->Data[Offset + 2], BFile->Data[Offset + 1], BFile->Data[Offset]);
break;
default:
Ret = RGB(0, 0, 0);
break;
}
return Ret;
}
//=============================================================
//语法格式: void BMP_CloseFile(void)
//实现功能: 关闭位图文件
//参数: BFile - BMP文件指针
//返回值: 无
//=============================================================
void BMP_CloseFile(BITMAP_FILE *BFile)
{
BFile->Opened = 0;
}
#if 0
int BMP_CreateFile(BITMAP_FILE *BFile, UINT8 *SaveAddr, UINT32 Width, UINT32 Height, INT32 BitMode)
{
BFile->LineWidth = (((BFile->InfoHead.Width * BFile->InfoHead.BitPerPixel) + 31) >> 5) BFile->InfoHead.HeadSize = 0x28;
BFile->InfoHead.Width = Width;
BFile->InfoHead.Height = Height;
BFile->InfoHead.Planes = 1;
if(BitMode==24)
{
BFile->InfoHead.BitPerPixel = 24;
BFile->InfoHead.DataSize = BFile->LineWidth * Height * 3;
}
else if(BitMode==16)
{
BFile->InfoHead.BitPerPixel = 16;
BFile->InfoHead.DataSize = BFile->LineWidth * Height * 2;
}
else
return -1;
BFile->InfoHead.CompresType = 0;
BFile->InfoHead.HResolution = 0;
BFile->InfoHead.VResolution = 0;
BFile->InfoHead.Colors = 0;
BFile->InfoHead.ImportColor = 0;
BFile->FileHead.Type = 0x4d42;
BFile->FileHead.FileSize = 0x36 + BFile->InfoHead.DataSize;
BFile->FileHead.Reserved = 0;
BFile->FileHead.Offset = 0x36;
memcpy(SaveAddr, (UINT8 *)BFile + 2, 0x36);
BFile->Data = SaveAddr + 0x36;
return 0;
}
void BMP_PutPixel(BITMAP_FILE *BFile, UINT16 x, UINT16 y, COLOR Color)
{
}
#endif