打印

发一个BMP RLE 解码程序

[复制链接]
3543|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ljx204|  楼主 | 2012-7-20 19:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天我才发现网上有很多人故意保留一些所谓的技术,我在网上寻找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

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

10

帖子

1

粉丝