金牌会员
 
- 积分
- 1896
- 金钱
- 1896
- 注册时间
- 2012-10-28
- 在线时间
- 357 小时
|
发表于 2014-11-2 21:28:02
|
显示全部楼层
回复【8楼】beyond696:
---------------------------------
你好,请问这个解码gif 的程序能否提供参考一下啊 ?、
我现在搞的gif 解码程序(是修改znFAT,我这个程序也是在网上找的,具体已经不记得是哪个论坛了),
显示只有图片的1/3显示基本正常,目前不知道是什么情况造成的,
有哪位大侠帮我看看啊 ??? 小弟不胜感激!!
部分程序如下:
#define USE_SD_CARD 1 //若需要支持SD卡显示GIF文件则需要将该宏定义为1
#define USE_SD_BUFFER 1 //若需要开辟SD卡读数据缓冲区则将该宏定义为1
/**************************************************************************************************************
* 函数名:GLCD_DrawHLine()
* 输入 :uint16_t Xpos, uint16_t Ypos, uint16_t Length 起点X和Y坐标及长度
* 输出 :void
* 描述 :画水平线
* 调用 :外部调用
* 调试OK
* LCD控制器:ILI9486
*****************************************************************************************************************/
void LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint16_t Color)
{
uint32_t i = 0;
LCD_SetCursor(Xpos, Xpos+Length, Ypos, Ypos+Length);
for(i = 0; i < Length; i++)
{
LCD_RAM = Color;
}
}
static uint8_t _ReadU8(void) {
uint8_t Value;
_Source.RemBytes -= 1;
if (_Source.RemBytes < 0) {
return 0;
}
// --------------------- 2014-11-02 ---------------------
#if USE_SD_CARD
#if USE_SD_BUFFER
if(ReceiveDataNum<=0)
{
// br = znFAT_ReadData(&FileInfo,FileInfo.File_CurOffset,4096,SD_Buffer); ??????
// ReceiveDataNum += br;
// f_lseek(&pic_fsrc, pic_fsrc.fsize); // f_size(&pic_fsrc) ????????????????????????????
f_read(&pic_fsrc, SD_Buffer, 4096, &pic_br);
ReceiveDataNum += pic_br;
ReadDataNum = 0;
}
ReceiveDataNum--;//缓冲区剩下的数据字节数减1
Value = SD_Buffer[ReadDataNum++]; //返回缓冲区的数据,同时将已读数据数加1
#else
// znFAT_ReadData(&FileInfo,FileInfo.File_CurOffset,1,&Value);
f_read(&pic_fsrc, SD_Buffer, 1, &pic_br);
#endif
#else
Value = *(_Source.pSrc++);
#endif
return Value;
}
static uint16_t _ReadU16(void) {
uint16_t Value;
uint8_t Byte0, Byte1;
Byte0 = _ReadU8();
Byte1 = _ReadU8();
Value = (Byte1 << 8) | Byte0;
return Value;
}
static void _ReadBytes(uint8_t * pBuffer, int Len) {
UINT br = 0;
#if USE_SD_BUFFER
int NeedDataNum;
#endif
if (_Source.RemBytes < 0) {
return;
}
if (_Source.RemBytes < Len) {
Len = _Source.RemBytes;
return;
}
_Source.RemBytes -= Len;
#if USE_SD_CARD
#if USE_SD_BUFFER
if(ReceiveDataNum<Len){
NeedDataNum = Len - ReceiveDataNum;
for(;ReceiveDataNum>0;ReceiveDataNum--){
*pBuffer++ = SD_Buffer[ReadDataNum++];
}
// br = znFAT_ReadData(&FileInfo,FileInfo.File_CurOffset,NeedDataNum,pBuffer); //????????????
// br = znFAT_ReadData(&FileInfo,FileInfo.File_CurOffset,4096,SD_Buffer);
// ReceiveDataNum += br;
// f_lseek(&pic_fsrc, pic_fsrc.fsize ); //f_size(&pic_fsrc) ?????????????????????
f_read(&pic_fsrc, pBuffer, NeedDataNum, &br);
f_read(&pic_fsrc, SD_Buffer, 4096, &br);
ReceiveDataNum += br;
ReadDataNum = 0;
}else{
for(;Len>0;Len--,ReceiveDataNum--){
*pBuffer++ = SD_Buffer[ReadDataNum++];
}
}
#else
// znFAT_ReadData(&FileInfo,FileInfo.File_CurOffset,Len,pBuffer);
f_read(&pic_fsrc, pBuffer, Len, &br);
#endif
#else
memcpy(pBuffer, _Source.pSrc, Len);
_Source.pSrc += Len;
#endif
}
static void _SkipBytes(int Len) {
if (_Source.RemBytes < 0) {
return;
}
if (_Source.RemBytes < Len) {
Len = _Source.RemBytes;
return;
}
_Source.RemBytes -= Len;
#if USE_SD_CARD
#if USE_SD_BUFFER
if(ReceiveDataNum>=Len){
ReceiveDataNum -= Len;
ReadDataNum += Len;
}else{
// znFAT_Seek(&FileInfo,FileInfo.File_CurOffset + Len-ReceiveDataNum);
f_lseek(&pic_fsrc, pic_fsrc.fsize + Len - ReceiveDataNum);
ReceiveDataNum = 0;
ReadDataNum = 0;
}
#else
// znFAT_Seek(&FileInfo,FileInfo.File_CurOffset + Len);
f_lseek(&pic_fsrc, pic_fsrc.fsize + Len);
#endif
#else
_Source.pSrc += Len;
#endif
}
static int _GetDataBlock(uint8_t * pBuffer) {
uint8_t Count;
Count = _ReadU8(); /* Read the length of the data block */
if (Count) {
if (pBuffer) {
_ReadBytes(pBuffer, Count);
} else {
#if USE_SD_CARD
#if USE_SD_BUFFER
if(ReceiveDataNum>=Count){
ReceiveDataNum -= Count;
ReadDataNum += Count;
}else{
// znFAT_Seek(&FileInfo,FileInfo.File_CurOffset + Count-ReceiveDataNum);
f_lseek(&pic_fsrc, pic_fsrc.fsize + Count - ReceiveDataNum);
ReceiveDataNum = 0;
ReadDataNum = 0;
}
#else
// znFAT_Seek(&FileInfo,FileInfo.File_CurOffset + Count);
f_lseek(&pic_fsrc, pic_fsrc.fsize + Count);
#endif
#else
_Source.pSrc += Count;
#endif
}
}
return((int)Count);
}
static int _DispGIFImage(IMAGE_DESCRIPTOR * pDescriptor, int x0, int y0, int Transparency, int Disposal) {
int Codesize, Index, OldIndex, XPos, YPos, YCnt,  ass, Interlace, XEnd;
int Width, Height, NumColors, Cnt, BkColorIndex, ColorIndex,TransparencyCnt=0;
const LCD_PIXELINDEX * pTrans;
Width = pDescriptor->XSize;
Height = pDescriptor->YSize;
NumColors = pDescriptor->NumColors;
XEnd = Width + x0 - 1;
BkColorIndex = BLACK;
pTrans = _aColorTable;//获取颜色索引表首地址
Codesize = _ReadU8(); /* Read the LZW codesize */
_InitLZW(Codesize); /* Initialize the LZW stack with the LZW codesize */
Interlace = pDescriptor->Flags & 0x40; /* Evaluate if image is interlaced */
if (Interlace){ //图像是交织排列的
for (YCnt = 0, YPos = y0,  ass = 0; YCnt < Height; YCnt++) {
Cnt = 0;
OldIndex = -1;
for (XPos = x0; XPos <= XEnd; XPos++) {
if (_LZWContext.sp > _LZWContext.aDecompBuffer) {
Index = *--(_LZWContext.sp);
} else {
Index = _GetNextByte();
}
if (Index == -2) {
return 0; // End code
}
if ((Index < 0) || (Index >= NumColors)) {
// If Index out of legal range stop decompressing
//while(1);
return 1; // Error
}
// If current index equals old index increment counter
if ((Index == OldIndex) && (XPos <= XEnd)) {
Cnt++;
} else {
if (Cnt) {
if (OldIndex != Transparency) {
// LCD_SetColorIndex(*(pTrans + OldIndex));
// ARC_LCD_DrawHLine(XPos - Cnt - 1, YPos, XPos - 1);
LCD_DrawHLine(XPos - Cnt - 1, YPos, XPos - 1, *(pTrans + OldIndex));
} else if (Disposal == 2) {
// LCD_SetColorIndex(BkColorIndex);
// ARC_LCD_DrawHLine(XPos - Cnt - 1, YPos, XPos - 1);
LCD_DrawHLine(XPos - Cnt - 1, YPos, XPos - 1, BkColorIndex);
}
Cnt = 0;
} else {
if (OldIndex >= 0) {
if (OldIndex != Transparency) {
// ARC_LCD_SetPixelIndex(XPos - 1, YPos, *(pTrans + OldIndex));
LCD_SetPoint(XPos - 1, YPos, *(pTrans + OldIndex));
} else if (Disposal == 2) {
// ARC_LCD_SetPixelIndex(XPos - 1, YPos, BkColorIndex);
LCD_SetPoint(XPos - 1, YPos, BkColorIndex);
}
}
}
}
OldIndex = Index;
}
if ((OldIndex != Transparency) || (Disposal == 2)) {
if (OldIndex != Transparency) {
ColorIndex = *(pTrans + OldIndex);
} else {
ColorIndex = BkColorIndex;
}
if (Cnt) {
// LCD_SetColorIndex(ColorIndex);
// ARC_LCD_DrawHLine(XPos - Cnt - 1, YPos, XPos - 1);
LCD_DrawHLine(XPos - Cnt - 1, YPos, XPos - 1, ColorIndex);
} else {
// ARC_LCD_SetPixelIndex(XEnd, YPos, ColorIndex);
LCD_SetPoint(XEnd, YPos, ColorIndex);
}
}
// Adjust YPos if image is interlaced
if (Interlace) {
YPos += _aInterlaceOffset[Pass];
if ((YPos - y0) >= Height) {
++Pass;
YPos = _aInterlaceYPos[Pass] + y0;
}
} else {
YPos++;
}
}
}
else
{ //图像是连续排列
// ARC_LCD_SetDisplayWindow(x0,y0,XEnd,y0+Height-1);
LCD_SetCursor(x0, XEnd, y0, y0 + Height-1);
for (YCnt = 0, YPos = y0,  ass = 0; YCnt < Height; YCnt++) {
Cnt = 0;
OldIndex = -1;
for (XPos = x0; XPos <= XEnd; XPos++) {
if (_LZWContext.sp > _LZWContext.aDecompBuffer) {
Index = *--(_LZWContext.sp);
} else {
Index = _GetNextByte();
}
if (Index == -2) {
return 0; // End code
}
if ((Index < 0) || (Index >= NumColors)) {
// If Index out of legal range stop decompressing
//while(1); //有的GIF图片会进入到这里,从而不能显示图片,Index==-1,原因待定
return 1; // Error
}
if(Index>=0){
if (Index != Transparency){
if(TransparencyCnt){
/*
#if (MAX_X == 480) && (MAX_Y == 320)
// ARC_LCD_WriteReg(LCD_REG_4EH, YPos); //ssd1289/ssd1298 起始地址
// ARC_LCD_WriteReg(LCD_REG_4FH, XPos);
LCD_WriteIndex(0x2b);
LCD_WriteData((u16)((319-YPos)>>8)); //起始地址
LCD_WriteData((u16)((319-YPos)&0x00FF));
LCD_WriteData((319-YPos)>>8); //结束地址
LCD_WriteData((319-YPos)&0x00FF);
LCD_WriteIndex(0x2a);
LCD_WriteData(XPos>>8); //起始地址
LCD_WriteData(XPos&0X00FF);
LCD_WriteData((XPos)>>8); //结束地址
LCD_WriteData((XPos)&0XFF);
#else
// ARC_LCD_WriteReg(LCD_REG_4EH, XPos);
// ARC_LCD_WriteReg(LCD_REG_4FH, YPos);
LCD_WriteIndex(0x2b);
LCD_WriteData(YPos>>8); //起始地址
LCD_WriteData(YPos&0X00FF);
LCD_WriteData((YPos)>>8); //结束地址
LCD_WriteData((YPos)&0XFF);
LCD_WriteIndex(0x2a);
LCD_WriteData((u16)((XPos)>>8)); //起始地址
LCD_WriteData((u16)((XPos)&0x00FF));
LCD_WriteData((XPos)>>8); //结束地址
LCD_WriteData((XPos)&0x00FF);
#endif
TransparencyCnt = 0;
// LCD_REG = LCD_REG_22H; //ssd1289/ssd1298 LCD控制器使用的显示控制 命令
// LCD_WriteRAM_Start();
*/
}
LCD_RAM = *(pTrans + Index);
}else if (Disposal == 2){
if(TransparencyCnt){
/*
#if (MAX_X == 480) && (MAX_Y == 320)
// ARC_LCD_WriteReg(LCD_REG_4EH, YPos);
// ARC_LCD_WriteReg(LCD_REG_4FH, XPos);
LCD_WriteIndex(0x2b);
LCD_WriteData((u16)((319-YPos)>>8)); //起始地址
LCD_WriteData((u16)((319-YPos)&0x00FF));
LCD_WriteData((319-YPos)>>8); //结束地址
LCD_WriteData((319-YPos)&0x00FF);
LCD_WriteIndex(0x2a);
LCD_WriteData(XPos>>8); //起始地址
LCD_WriteData(XPos&0X00FF);
LCD_WriteData((XPos)>>8); //结束地址
LCD_WriteData((XPos)&0XFF);
#else
// ARC_LCD_WriteReg(LCD_REG_4EH, XPos);
// ARC_LCD_WriteReg(LCD_REG_4FH, YPos);
LCD_WriteIndex(0x2b);
LCD_WriteData(YPos>>8); //起始地址
LCD_WriteData(YPos&0X00FF);
LCD_WriteData((YPos)>>8); //结束地址
LCD_WriteData((YPos)&0XFF);
LCD_WriteIndex(0x2a);
LCD_WriteData((u16)((XPos)>>8)); //起始地址
LCD_WriteData((u16)((XPos)&0x00FF));
LCD_WriteData((XPos)>>8); //结束地址
LCD_WriteData((XPos)&0x00FF);
#endif
TransparencyCnt = 0;
// LCD_REG = LCD_REG_22H;
// LCD_WriteRAM_Start();
*/
}
LCD_RAM = BkColorIndex;
}else{//颜色为透明色,也就是不需要在LCD的这个点输出颜色,但是内部地址需要递增
TransparencyCnt++;
}
}
}
YPos++;
}
}
return 0;
} |
|