📄 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 + -