taozhihua1314 发表于 2012-8-26 12:09:29

BMP图片解码

//*****************************************************************************//
//*                                                                数码相框
//*控制芯片:ATmgea128
//*开发环境:AVR Studio+GCC
//*隶属模块:位图解码
//*设计者:桃子
//*****************************************************************************//
#include "bmp.h"

extern unsigned char buffer;        //文件系统数据缓冲
extern FATFS   fs;                                        //文件系统结构
extern FIL   fl;                                        //文件状态信息
extern FRESULT res;                                        //文件返回值
extern unsigned int r;                                //文件读取数量
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:小端转大端
//****************************************************************
UINT32 bmp_LE2BE(UINT8 *dat,UINT8 len)
{
        UINT32 temp=0;

        if(len >= 1) temp= (UINT32)dat;
        if(len >= 2) temp |= (UINT32)dat<<8;
        if(len >= 3) temp |= (UINT32)dat<<16;
        if(len >= 4) temp |= (UINT32)dat<<24;

        return temp;
}
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:单灰BMP解码显示
//*注意:图片宽度最好小于208
//****************************************************************
void BMP_1(unsigned int x0,unsigned int y0,unsigned char type)
{
        unsigned int j;
        unsigned char k=0;

        if(BMP.bmp_width & 0x001f)BMP.bmp_width +=32 - (BMP.bmp_width & 0x001f);

        if(type)
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        else
        {
                x0 = (240 - BMP.bmp_width)/2;
                y0 = (320 - BMP.bmp_hight)/2;
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        }

        while(1)
        {
                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;
                for(j=0;j<r;j++)
                {       
                        for(k=8;k;k--)
                        {
                                if(buffer & (1 << (k-1)))
                                        TFT_Write_Data(0x00,0x00);
                                else
                                        TFT_Write_Data(0xff,0xff);
                        }       
                }                                          
        }
}
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:16位灰BMP解码显示
//*注意:图片宽度最好小于232
//****************************************************************
void BMP_4(unsigned int x0,unsigned int y0,unsigned char type)
{
        unsigned int j;
        unsigned char color_H,color_L,i;
        const unsigned char table_RBGcolor = {0xff,0xee,0xdd,0xcc,0xbb,0xaa,//经查表RGB三像素相同
                                                                                          0x99,0x88,0x77,0x66,0x55,0x44,//从白到黑FF~00共16个
                                                                                          0x33,0x22,0x11,0x00};         //段

        if(BMP.bmp_width & 0x0007)BMP.bmp_width +=8 - (BMP.bmp_width & 0x007);

        if(type)
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        else
        {
                x0 = (240 - BMP.bmp_width)/2;
                y0 = (320 - BMP.bmp_hight)/2;
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        }

        while(1)
        {
                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;

                for(j=0;j<r;j++)
                {
                        i = buffer>> 4;
                        color_H = (table_RBGcolor & 0xf8) | (table_RBGcolor >> 5);
                        color_L = ((table_RBGcolor << 3) & 0xe0) | (table_RBGcolor >> 3);
                        TFT_Write_Data(color_H,color_L);
                       
                        i = buffer& 0x0f;
                        color_H = (table_RBGcolor & 0xf8) | (table_RBGcolor >> 5);
                        color_L = ((table_RBGcolor << 3) & 0xe0) | (table_RBGcolor >> 3);
                        TFT_Write_Data(color_H,color_L);       
                }                                          
        }
}
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:256位灰BMP解码显示
//*注意:图片宽度最好小于236
//****************************************************************
void BMP_8(unsigned int x0,unsigned int y0,unsigned char type)
{
        const unsigned char table_Bcolor = {0x00,0x55,0xaa,0xff};//经查表R像素
        const unsigned char table_GRcolor = {0x00,0x24,0x48,0x6d,0x91,0xb6,0xda,0xff};//经查表GB像素相同

        unsigned int j;
        unsigned char color_H,color_L;       


        if(BMP.bmp_width & 0x0003)BMP.bmp_width +=4 - (BMP.bmp_width & 0x03);

        if(type)
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        else
        {
                x0 = (240 - BMP.bmp_width)/2;
                y0 = (320 - BMP.bmp_hight)/2;
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        }

        while(1)
        {
                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;
                for(j=0;j<r;j++)
                {
                        color_H = (table_Bcolor>>6] & 0xf8) | (table_GRcolor[(buffer & 0x38)>>3] >> 5);
                        color_L = ((table_GRcolor[(buffer & 0x38)>>3] << 3) & 0xe0) | (table_GRcolor & 0x07] >> 3);
                        TFT_Write_Data(color_H,color_L);       
                }                                          
        }
}

//****************************************************************
//*隶属模块:BMP解码
//*函数功能:16位真彩BMP解码显示
//****************************************************************
void BMP_16(unsigned int x0,unsigned int y0,unsigned char type)
{
        unsigned int j=0;
        unsigned int temp_color=0;
        if(BMP.bmp_width & 0x0001)BMP.bmp_width +=1;

        if(type)
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        else
        {
                x0 = (240 - BMP.bmp_width)/2;
                y0 = (320 - BMP.bmp_hight)/2;
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        }
        while(1)
        {
                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;
                for(j=0;j<r;j+=2)
                {
                        temp_color = ((buffer&0xE0)<<1)|(buffer&0x1F);
                        TFT_Write_Data((buffer<<1)|(temp_color>>8),temp_color&0x00FF);
               
                }                                  
        }
}
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:24位真彩BMP解码显示
//****************************************************************
void BMP_24(unsigned int x0,unsigned int y0,unsigned char type)
{
        unsigned int j=0;
        unsigned char temp;

        if(BMP.bmp_width & 0x0003)BMP.bmp_width +=4 - (BMP.bmp_width & 0x03);

        if(type)
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        else
        {
                x0 = (240 - BMP.bmp_width)/2;
                y0 = (320 - BMP.bmp_hight)/2;
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        }

        while(1)
        {
                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;
                temp = buffer;temp = buffer;
                for(j=0;j<r-2;j+=3)
                {       
                        TFT_Write_Data((buffer&0xf8)|(buffer>>5),
                                                           ((buffer<<3)&0xe0)|(buffer>>3));                                  
                }


                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;

                TFT_Write_Data((buffer&0xf8)|(temp>>5),
                                           ((temp<<3)&0xe0)|(temp>>3));
                                                          
                temp = buffer;
                for(j=1;j<r-1;j+=3)
                {       
                        TFT_Write_Data((buffer&0xf8)|(buffer>>5),
                                           ((buffer<<3)&0xe0)|(buffer>>3));                                  
                }


                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;

                TFT_Write_Data((buffer&0xf8)|(buffer>>5),
                                           ((buffer<<3)&0xe0)|(temp>>3));
                for(j=2;j<r;j+=3)
                {       
                        TFT_Write_Data((buffer&0xf8)|(buffer>>5),
                                                   ((buffer<<3)&0xe0)|(buffer>>3));                                  
                }

        }
}
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:32位真彩BMP解码显示
//****************************************************************
void BMP_32(unsigned int x0,unsigned int y0,unsigned char type)
{
        unsigned int j=0;

        if(type)
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        else
        {
                x0 = (240 - BMP.bmp_width)/2;
                y0 = (320 - BMP.bmp_hight)/2;
                TFT_Windons(x0,x0+BMP.bmp_width-1,y0,y0+BMP.bmp_hight-1);
        }
        while(1)
        {
                res = f_read(&fl,buffer,512,&r);
                if(res || r==0) break;
                for(j=0;j<r;j+=4)
                {       
                        TFT_Write_Data((buffer&0xf8)|(buffer>>5),
                                                           ((buffer<<3)&0xe0)|(buffer>>3));                                  
                }
        }
}
//****************************************************************
//*隶属模块:BMP解码
//*函数功能:BMP图片格式解码
//****************************************************************
void dis_bmp(unsigned int x0,unsigned int y0,unsigned char type)
{       
        do
        {
                res = f_read(&fl,buffer,512,&r);//读512个数据          
        }while(res || r==0);
        BMP.bmp_offset = bmp_LE2BE((buffer + 10),4);//数据偏移量
        BMP.bmp_width= (UINT16)(bmp_LE2BE((buffer + 18),4));//图像宽度
        BMP.bmp_hight= (UINT16)(bmp_LE2BE((buffer + 22),4));//说明图像高度
        BMP.bmp_form   = (UINT16)(bmp_LE2BE((buffer + 28),2));//说明图像格式
        do{
                res = f_lseek(&fl,BMP.bmp_offset);
        }while(res);
        if(type == 2)
                {BMP.bmp_width >>= 1;BMP.bmp_hight >>= 1;}
        else if(type == 4)
                        {BMP.bmp_width >>= 2;BMP.bmp_hight >>= 2;}
        switch(BMP.bmp_form)
        {
                case 1: BMP_1(x0,y0,type); break;
                case 4: BMP_4(x0,y0,type); break;       
                case 8: BMP_8(x0,y0,type); break;
                case 16:BMP_16(x0,y0,type);break;
                case 24:BMP_24(x0,y0,type);break;
                case 32:BMP_32(x0,y0,type);break;
                default:break;
        }               
        f_close(&fl);
        f_mount(0,NULL);
}

wuguoyan 发表于 2012-8-26 12:35:03

写的比较齐全了,顶起~~

kneken 发表于 2012-8-26 12:54:52

支持一下!!

taozhihua1314 发表于 2012-9-7 21:45:40

纯属自个乐乐,望大侠拍砖。{:smile:}

wind2100 发表于 2012-9-7 21:49:20

不错 数码相框 出来一半了

taozhihua1314 发表于 2012-9-7 21:50:55

文件系统采用 fatfs0.9

loveye21 发表于 2012-9-7 21:53:24

谢谢啦,正是我要的

halloocc 发表于 2012-9-7 21:53:58

不错,捡果子了 {:lol:}

taozhihua1314 发表于 2012-9-7 22:03:27

呵呵,大伙一起改改。
TFT 驱动是9320

doolheey 发表于 2012-9-8 21:44:07

还没有接触到图片的。先看看:)

shiy 发表于 2013-1-19 17:33:01

收藏了      {:time:}

kenson 发表于 2013-1-19 17:39:56

{:hug:} 不错 收了!

残忆视觉 发表于 2014-2-24 19:21:14

谢谢,学习学习
页: [1]
查看完整版本: BMP图片解码