⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gif.c

📁 自己写的单片机系统用GIF显示程序
💻 C
字号:
#include "stdlib.h"
#include "LCD.h"
#include "gif.h"
#include "LCD_Module.h"
#include "other.h"

extern unsigned char Image_data[0x200][0x350];
extern struct  StringItem StringTable[4096];
extern unsigned char file_data[0x70000];

unsigned int gifWidth,gifHeight;
unsigned int gifxStart,gifyStart;
unsigned int x_GifOffset,y_GifOffset;
unsigned int curGifWidth,curGifHeight;

unsigned int psize;//Global Color table size
unsigned int N,CC,EOI;
unsigned char trans;
unsigned char interlace;
unsigned char bkcolor;
unsigned char transflag;

extern unsigned char f_stopDelay;

void DispGif(unsigned char *pGif)
{

unsigned char *p;	
unsigned int pstep;
 
p=pGif;
pstep=0;

if(!ReadGifHead(p)) return;
p=p+6;
if(!ReadGifInfo(p)) return;
p=p+7+psize;
 
while(*p!=0x3B)
{
 if(*p==0x2c) 
  { pstep=LZWdecode(p)+1;
  //LoadGIFfile();
  DispImage(0,0,LCD_width,LCD_height);
  }
 //handle comment extension block
 if(*p==0x21)
  {	
	switch(*(p+1))
	  { case 0xF9: pstep=F9(p);break;
		case 0xFE:
		case 0xFF: 
		case 0x01:
		           pstep=*(p+2)+3;
		           while(*(p+pstep)!=0x00)
	                {pstep+=*(p+pstep)+1;}
	               pstep++;
		           break;
		default: return;
	   } 
  }
 p=p+pstep;         //move p to next block
 }

}

void DisplayGif(unsigned char *pGif,unsigned char gifmode)
{
 DispPattern(0xffffff,0,0,LCD_width,LCD_height);
 do
 {
  DispGif(pGif);
 }while(!f_stopDelay && !gifmode);
 f_stopDelay=0;
 
}

unsigned int LZWdecode(unsigned char *pGif)
{

unsigned char *p;

struct StringItem tempString;

unsigned int codeBuf;
unsigned char curLen;
unsigned int curTable;
unsigned int rst;
unsigned char remainBits;

unsigned int i;
unsigned char DataCount;
unsigned int bsize;

struct point *xyPoint;;
xyPoint=(struct point *)malloc(POINT_LEN);  
p=pGif;

x_GifOffset=*(p+2)*256+*(p+1);
y_GifOffset=*(p+4)*256+*(p+3);
curGifWidth=*(p+6)*256+*(p+5);
curGifHeight=*(p+8)*256+*(p+7);
xyPoint->x=x_GifOffset;
xyPoint->y=y_GifOffset;
interlace=(*(p+9))&0x40;
bsize=10;

p=p+bsize;
N=*p++; CC=1<<N; EOI=CC+1;//decoder element
DataCount=*p++;
bsize+=DataCount+1;

//initialize default string table
curLen=N+1;  curTable=EOI;
for(i=0;i<CC;i++)
  StringTable[i].firstPrefix=i;
for(i=0;i<CC;i++)
  StringTable[i].lastPrefix=EOI;
  
codeBuf=0;remainBits=0;
while(1)
{
  while(remainBits<curLen)
  { if(DataCount==0)
 	 if(*p!=00)
 	  {DataCount=*p++;bsize+=DataCount+1;}//code data size larger than a data block
 	 
   codeBuf|=(*p++)<<remainBits;
   remainBits+=8;
   DataCount--;
  }
 rst=codeBuf&(0xfff>>(12-curLen));//pick up compress code
 remainBits-=curLen;
 codeBuf>>=curLen;
 
 if((curTable+1)>>curLen)  curLen+=1;


// if(pos>=gifWidth*gifHeight)   break; 
 if(rst==CC)
   {curTable=EOI;curLen=N+1;continue; }
 else    //have reached the end of a picture,and then inc bsize beacause of the end-flag:0
  if(rst==EOI)  { bsize++; break; } 
 
 if(curTable==EOI)
   { 
     LoadDecodeDataToBuf(xyPoint,(unsigned char)rst);
     tempString.firstPrefix=rst;
   }
 else      
  {  
    if(rst<curTable)
     {
       SearchInStringTable(xyPoint,rst);
       tempString.lastPrefix=SearchFirstCh(rst);
       StringTable[curTable]=tempString;
       tempString.firstPrefix=rst;
     }
    else
     {
       tempString.lastPrefix=SearchFirstCh(tempString.firstPrefix);
       SearchInStringTable(xyPoint,tempString.firstPrefix);
       LoadDecodeDataToBuf(xyPoint,tempString.lastPrefix);
       StringTable[curTable]=tempString;
       tempString.firstPrefix=rst;
     }
    }
    curTable++;

  }
free(xyPoint);
return bsize;
}

void LoadDecodeDataToBuf(struct point *xy,unsigned char decodeData)

{
 unsigned char i;
 i=decodeData;
 if(i!=trans||transflag!=1)
 {
  Image_data[gifyStart+xy->y][(gifxStart+xy->x)*3]=file_data[0xd+i*3];
  Image_data[gifyStart+xy->y][(gifxStart+xy->x)*3+1]=file_data[0xd+i*3+1];
  Image_data[gifyStart+xy->y][(gifxStart+xy->x)*3+2]=file_data[0xd+i*3+2];
 
 }
 
 if(!interlace)
   { xy->x+=1;
     if(xy->x==x_GifOffset+curGifWidth)
      {xy->x=x_GifOffset;xy->y++;}
   }
 else
  {
    xy->x+=1;
    if(xy->x==x_GifOffset+curGifWidth)
     { xy->x=x_GifOffset;
       if((xy->y-y_GifOffset)%8==0)   //pass 1
        { xy->y+=8;
         if(xy->y>=(y_GifOffset+curGifHeight))  xy->y=y_GifOffset+4;
        }
       else
       if((xy->y-y_GifOffset)%8==4)  //pass 2
        { xy->y+=8;
         if(xy->y>=(y_GifOffset+curGifHeight))  xy->y=y_GifOffset+2;
        }
       else
       if((xy->y-y_GifOffset)%4==2)  //pass 3
        { xy->y+=4;
         if(xy->y>=(y_GifOffset+curGifHeight)) xy->y=y_GifOffset+1;
        }
       else
       if((xy->y-y_GifOffset)%2==1)  //pass 4
        {
         xy->y+=2;
        }
     }
  }   
}
void SearchInStringTable(struct point *gifPoint ,unsigned int codeNum)
{ unsigned int temp;
  
  temp=StringTable[codeNum].firstPrefix;
  if(temp!=EOI)///=5 need FIX
   {
    if(temp>EOI)//EOI
       SearchInStringTable(gifPoint,temp);
    else
       LoadDecodeDataToBuf(gifPoint,(unsigned char)temp); 
    }
  temp=StringTable[codeNum].lastPrefix;
  if(temp!=EOI)//
  {
    if(temp>EOI)//
      SearchInStringTable(gifPoint,temp);
    else
      LoadDecodeDataToBuf(gifPoint,(unsigned char)temp);
   }   
}



unsigned int SearchFirstCh(unsigned int codeNum)
{ unsigned int temp;
  
  temp=StringTable[codeNum].firstPrefix;
  while(temp!=EOI && temp>EOI)//=5
  {
   temp=StringTable[temp].firstPrefix;
   }
  return temp; 
    
}
  
//added 
unsigned char ReadGifHead(unsigned char *p)
{	if(*p!='G')  return 0;
	if(*(p+1)!='I') return 0;
	if(*(p+2)!='F')  return 0;
	return 1;
}

unsigned char ReadGifInfo(unsigned char *p)
{	unsigned char temp;
	unsigned char pratio;
	unsigned char mflag;
	gifWidth=(*p++);
	gifWidth+=(*p++)<<8;
	gifHeight=(*p++);
	gifHeight+=*p<<8;
	gifxStart=(LCD_width-gifWidth)/2;
	gifyStart=(LCD_height-gifHeight)/2;
	p++;
	temp=*p;
	if((temp&0x80)==0x80)
		{	mflag=1;
			psize=1<<((temp&0x07)+1);
			psize=psize*3;
		}
	p++;
	bkcolor=*p;
	p++;
	pratio=*p;
	return mflag;
}

unsigned char F9(unsigned char *p)
{	unsigned char bsize;
	unsigned int delaytime;
	unsigned char disposal;
	bsize=2;
	bsize+=*(p+2)+1;
	transflag=(*(p+3))&1;
	if(transflag) trans=*(p+6);
	//delay	
	delaytime=(*(p+4))+((*(p+5))<<8);
	Delayms1(delaytime*8);
	disposal=((*(p+3))&0x1C)>>2;
	if(disposal==2)
	 FillBkColor(bkcolor);
	bsize++;
	return bsize;
}


void FillBkColor(unsigned char bkcolor)
{
 unsigned int i,j;
 for(i=gifyStart+y_GifOffset;i<y_GifOffset+gifyStart+gifHeight;i++)
  for(j=gifxStart+y_GifOffset;j<y_GifOffset+gifxStart+gifWidth;j++)
   {Image_data[i][j*3]=0xff;//file_data[0xd+bkcolor*3];
    Image_data[i][j*3+1]=0xff;//file_data[0xd+bkcolor*3+1];
    Image_data[i][j*3+2]=0xff;//file_data[0xd+bkcolor*3+2];
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -