今天我才发现网上有很多人故意保留一些所谓的技术,我在网上寻找BMP RLE-8的解码
程序和资料,发现只说不做,而且还误导了我.
自力更生,我自己写了一个,是嵌入式的,我解码显示在LCD 上,可以正常工作.
BMP-RLE 是用 Photoshop 生成的,希望对有需要的人帮助.
#ifndef __SOFTBMP_H__
#define __SOFTBMP_H__
struct bmp_head {
char map_id[2]; //标识符,识别位图类型,一般为‘B’‘M’
unsigned int file_size; //用字节表示整个文件的大小
int reserved; //保留,设置为0
unsigned int offset; //从文件开始到位图数据开始之间的数据(bitmap data)之间的 //偏移量
};
/*bmp位图信息*/
struct bmp_info {
unsigned int cur_size; //当前结构体的大小,通常是40或56
int width; //位图的宽度,以像素为单位
int hight; //位图的高度,以像素为单位
short reserved; //这个字的值永远是1
short bpp; //每像素占用的位数,即bpp
unsigned int compression;//压缩方式
unsigned int map_size; //用字节数表示的位图数据的大小。该数必须是4的倍数
int x_ppm; //用像素/米表示的水平分辨率
int y_ppm; //用像素/米表示的垂直分辨率
unsigned int palette; //调色板规范
unsigned int bitmapdata;//该域的大小取决于压缩方法,它包含所有的位图数据字节, //这些数据实际就是彩色调色板的索引号
/*cur_size = 40不包含以下信息,=56时则包含之*/
unsigned int R;
unsigned int G;
unsigned int B;
unsigned int A;
};
typedef struct tagBITMAPFILEHEADER
{
INT16U bfType; // 位图文件的类型,必须为BM(0-1字节)
INT32U bfSize; // 位图文件的大小,以字节为单位(2-5字节)
INT16U bfReserved1; // 位图文件保留字,必须为0(6-7字节)
INT16U bfReserved2; // 位图文件保留字,必须为0(8-9字节)
INT32U bfOffBits; // 说明实际图形数据的偏移量(10-13字节)
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
INT32U biSize; //说明BITMAPINFOHEADER结构所需字节数
INT32U biWidth; //说明图像宽度
INT32U biHeight; //说明图像高度
//为目标设备说明位面数,其值设为1
INT16U biPlanes;
INT16U biBitCount; //每个像素的位数,单色位图为1,256色为8,24bit为24。
INT32U biCompression; //压缩说明,BI_RGB:无压缩,BI_RLE8:8位RLE压缩,BI_RLE4:4位RLE压缩
INT32U biSizeImage; //说明图像大小,如无压缩,可设为0
INT32U biXPelsPerMerer; //水平分辨率
INT32U biYPelsPerMerer; //垂直分辨率
INT32U biClrUsed; //位图使用的颜色数
INT32U biClrImportant; //重要颜色数目
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
INT8U rgbBlue; // 指定蓝色强度
INT8U rgbGreen; //指定绿色强度
INT8U rgbRed; //指定红色强度
INT8U rgbReserved; //保留,设为0
}RGBQUAD;
///-------------------------------------------------------------
#include "softbmp.h"
INT32U Crib_decode_bmp(CHAR *p_name, INT16U * p_buf)
{
BITMAPFILEHEADER head;
BITMAPINFOHEADER info;
INT32S file_handle;
INT32U ret, i, j, k;
INT16U temp1, temp2;
INT8U *buffer_data;
INT16S W, H;
RGBQUAD rgb;
INT16U * p_pal;
file_handle = (INT32U)open(p_name, O_RDONLY);
if(file_handle < 0)
{
return 1;
}
ret = read(file_handle, (INT32U)&head.bfType, sizeof(head.bfType));
if(ret != sizeof(head.bfType))
{
return 1;
}
ret = read(file_handle, (INT32U)&head.bfSize, sizeof(head.bfSize));
if(ret != sizeof(head.bfSize))
{
return 1;
}
ret = read(file_handle, (INT32U)&head.bfReserved1, sizeof(head.bfReserved1));
if(ret != sizeof(head.bfReserved1))
{
return 1;
}
ret = read(file_handle, (INT32U)&head.bfReserved2, sizeof(head.bfReserved2));
if(ret != sizeof(head.bfReserved2))
{
return 1;
}
ret = read(file_handle, (INT32U)&head.bfOffBits, sizeof(head.bfOffBits));
if(ret != sizeof(head.bfOffBits))
{
return 1;
}
//------------------------------------
ret = read(file_handle, (INT32U)&info.biSize, sizeof(info.biSize));
if(ret != sizeof(info.biSize))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biWidth, sizeof(info.biWidth));
if(ret != sizeof(info.biWidth))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biHeight, sizeof(info.biHeight));
if(ret != sizeof(info.biHeight))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biPlanes, sizeof(info.biPlanes));
if(ret != sizeof(info.biPlanes))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biBitCount, sizeof(info.biBitCount));
if(ret != sizeof(info.biBitCount))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biCompression, sizeof(info.biCompression));
if(ret != sizeof(info.biCompression))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biSizeImage, sizeof(info.biSizeImage));
if(ret != sizeof(info.biSizeImage))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biXPelsPerMerer, sizeof(info.biXPelsPerMerer));
if(ret != sizeof(info.biXPelsPerMerer))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biYPelsPerMerer, sizeof(info.biYPelsPerMerer));
if(ret != sizeof(info.biYPelsPerMerer))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biClrUsed, sizeof(info.biClrUsed));
if(ret != sizeof(info.biClrUsed))
{
return 1;
}
ret = read(file_handle, (INT32U)&info.biClrImportant, sizeof(info.biClrImportant));
if(ret != sizeof(info.biClrImportant))
{
return 1;
}
//------------------------------------------------------
if(head.bfType != 0x4D42)
{
return 1;
}
if(info.biBitCount != 8)
{
return 1;
}
if(info.biHeight != 600) return 1;
if(info.biWidth != 1024) return 1;
p_pal = (INT16U *)gp_malloc(256*2);
for(i = 0; i < 256; i++)
{
read(file_handle, (INT32U)&rgb, sizeof(rgb));
temp1 = rgb.rgbRed;
temp1 >>= 3;
temp1 <<= 11;
temp2 = rgb.rgbGreen;
temp2 >>= 2;
temp2 <<= 5;
temp1 |= temp2;
temp2 = rgb.rgbBlue;
temp2 >>= 3;
temp1 |= temp2;
p_pal[i] = temp1;
}
lseek(file_handle, head.bfOffBits, SEEK_SET);
if(info.biCompression == 0)
{
W=(info.biWidth+3)/4*4;
buffer_data = gp_malloc(W);
j = 0;
for(H=info.biHeight-1; H>=0; H--)
{
read(file_handle, (INT32U)buffer_data, W);
for(i = 0; i < info.biWidth; i++)
{
p_buf[H*info.biWidth + i] = p_pal[buffer_data[i]];
}
}
close(file_handle);
gp_free(p_pal);
gp_free(buffer_data);
return 0;
}
else if(info.biCompression == 1)
{ //RLE-8
INT8U RLE_Len;
INT8U RLE_index;
INT8U kk;
j = 0;
H=info.biHeight-1;
while(1)
{
read(file_handle, (INT32U)&RLE_Len, 1);
read(file_handle, (INT32U)&RLE_index, 1);
if(RLE_Len == 0x00){
if(RLE_index == 0x01) break;
else if(RLE_index == 0x00) {
j = 0;
H--;
if(H < 0) { //错误,严重错误
close(file_handle);
gp_free(p_pal);
return 1;
}
}
else if(RLE_index == 0x02) {
read(file_handle, (INT32U)&RLE_Len, 1);
read(file_handle, (INT32U)&RLE_index, 1);
}
else {
// kk = ((RLE_index + 3)/4) * 4;
kk = RLE_index%2;
for(k = 0; k < RLE_index; k++)
{
read(file_handle, (INT32U)&RLE_Len, 1);
p_buf[H*info.biWidth + j] = p_pal[RLE_Len];
j++;
}
k = 0;
while(k < kk)
{
read(file_handle, (INT32U)&RLE_Len, 1);
k++;
}
}
}
else {
for(k = 0; k < RLE_Len; k++ ) {
p_buf[H*info.biWidth + j] = p_pal[RLE_index];
j++;
}
}
}
close(file_handle);
gp_free(p_pal);
return 0;
}
else {
close(file_handle);
gp_free(p_pal);
return 1;
}
}
#endif |
|