📄 gif89a.cpp
字号:
//#include <fstream.h>
#include "stdafx.h"
#include <string.h>
#include "gif89a.h"
CGif89a::CGif89a()
{ opened = FALSE;
error = FALSE;
}
CGif89a::CGif89a(LPCTSTR fileName,BOOL inMem)
{ opened = FALSE; //
error = FALSE; //
if(open(fileName,inMem))
{ opened = TRUE;
error = FALSE;
}
else
{ opened = FALSE;
error = TRUE;
}
}
CGif89a::~CGif89a()
{ close();
}
BOOL CGif89a::operator!()
{ return error;
}
BOOL CGif89a::open(LPCTSTR filename,BOOL b)
{ char cc[4];
BYTE be;
BOOL fileEnd = FALSE;
inMem = b;
allFrames = NULL;
curIndex = 0;
curFrame.pColorTable = NULL;
curFrame.dataBuf = NULL;
ctrlExt.active = FALSE;
if(opened)
return FALSE;
//ifs.open(fileName,ios::binary);
ifs=_tfopen(filename,L"rb");//wince
//ifs=fopen(filename,"rb");//win32
if(!ifs)
return FALSE;
//ifs.read(cc,3);
fread((char*)cc,1,3,ifs);
if(strncmp(cc,"GIF",3) != 0)
goto error;
//ifs.read(version,3);
fread((char*)version,1,3,ifs);
version[3] = 0;
if(strncmp(version,"89a",3)!=0 ||strncmp(version,"89a",3)!=0)//???
goto error;
//ifs.read((char*)&gInfo.scrWidth,2);
fread((char*)&gInfo.scrWidth,1,2,ifs);
//ifs.read((char*)&gInfo.scrHeight,2);
fread((char*)&gInfo.scrHeight,1,2,ifs);
//if(!ifs.good())
// goto error;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
if((be&0x80) != 0)
gInfo.gFlag = TRUE;
else
gInfo.gFlag = FALSE;
gInfo.colorRes = ((be&0x70)>>4)+1;
if(gInfo.gFlag)
{ if((be&0x08) != 0)
gInfo.gSort = TRUE;
else
gInfo.gSort = FALSE;
gInfo.gSize = 1;
gInfo.gSize <<= ((be&0x07)+1);
}
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
gInfo.BKColorIdx = be;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
gInfo.pixelAspectRatio = be;
//if(!ifs.good())
// goto error;
if(gInfo.gFlag)
{
//ifs.read((char*)gColorTable,gInfo.gSize*3);
fread((char*)gColorTable,1,gInfo.gSize*3,ifs);
gInfo.gColorTable = gColorTable;
}
else
gInfo.gColorTable = NULL;
//dataStart = ifs.tellg();
dataStart=ftell(ifs);
//skip for speed ,but ginfo.frame also skip,no effect
if((gInfo.frames = checkFrames(ifs)) == 0)
goto error;
fseek(ifs,dataStart,SEEK_SET);//
if(inMem)
{ if((allFrames = new FRAME[gInfo.frames]) == NULL)
goto error;
ZeroMemory(allFrames,sizeof(FRAME)*gInfo.frames);
if(!getAllFrames(ifs))
{ delete[] allFrames;
allFrames = NULL;
goto error;
}
fclose(ifs);
}
opened = TRUE;
return TRUE;
error:
//ifs.close();
fclose(ifs);
return FALSE;
}
UINT CGif89a::checkFrames(FILE *ifs)
{ BYTE be;
BOOL fileEnd = FALSE;
UINT frames=0;
//streampos pos = ifs.tellg();
long pos = ftell(ifs);
//while(!ifs.eof() && !fileEnd)
while(!feof(ifs) && !fileEnd)
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
switch(be)
{ case 0x21:
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
switch(be)
{ case 0xf9:
case 0xfe:
case 0x01:
case 0xff:
//while(!ifs.eof())
while(!feof(ifs))
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
if(be == 0)
break;
//ifs.seekg(be,ios::cur);
fseek(ifs,be,SEEK_CUR);
}
break;
default:
return 0;
}
break;
case 0x2c:
{ BYTE bp;
BOOL lFlag=FALSE;
UINT lSize=1;
frames++;
//ifs.seekg(8,ios::cur);
fseek(ifs,8,SEEK_CUR);
//ifs.read((char*)&bp,1);
fread((char*)&bp,1,1,ifs);
if((bp&0x80) != 0)
lFlag = TRUE;
lSize <<= ((bp&0x07)+1);
if(lFlag)
//ifs.seekg(lSize*3,ios::cur);
fseek(ifs,lSize*3,SEEK_CUR);
//if(!ifs.good())
// return 0;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
//while(!ifs.eof())
while(!feof(ifs))
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
if(be == 0)
break;
//ifs.seekg(be,ios::cur);
fseek(ifs,be,SEEK_CUR);
}
break;
}
case 0x3b:
fileEnd = TRUE;
break;
case 0x00:
break;
default:
return 0;
}
}
//ifs.seekg(pos);
fseek(ifs,pos,SEEK_SET);
return frames;
}
BOOL CGif89a::getAllFrames(FILE *ifs)
{ BYTE be;
BOOL fileEnd = FALSE;
FRAME *pf = allFrames;
//streampos pos = ifs.tellg();
long pos=ftell(ifs);
int i;
//while(!ifs.eof() && !fileEnd)
while(!feof(ifs) && !fileEnd)
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
switch(be)
{ case 0x21:
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
switch(be)
{ case 0xf9:
//while(!ifs.eof())
while(!feof(ifs))
{ fread((char*)&be,1,1,ifs);
if(be == 0)
break;
if(be == 4)
{ ctrlExt.active = TRUE;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
ctrlExt.disposalMethod = (be&0x1c)>>2;
if((be&0x02) != 0)
ctrlExt.userInputFlag = TRUE;
else
ctrlExt.userInputFlag = FALSE;
if((be&0x01) != 0)
ctrlExt.trsFlag = TRUE;
else
ctrlExt.trsFlag = FALSE;
//ifs.read((char*)&ctrlExt.delayTime,2);
fread((char*)&ctrlExt.delayTime,1,2,ifs);
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
ctrlExt.trsColorIndex = be;
}
else
//ifs.seekg(be,ios::cur);
fseek(ifs,be,SEEK_CUR);
}
break;
case 0xfe:
case 0x01:
case 0xff:
//while(!ifs.eof())
while(!feof(ifs))
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
if(be == 0)
break;
//ifs.seekg(be,ios::cur);
fseek(ifs,be,SEEK_CUR);//2006.6.8
}
break;
default:
goto error;
}
break;
case 0x2c:
{ BYTE bp;
//ifs.read((char*)&pf->imageLPos,2);
fread((char*)&pf->imageLPos,1,2,ifs);
//ifs.read((char*)&pf->imageTPos,2);
fread((char*)&pf->imageTPos,1,2,ifs);
//ifs.read((char*)&pf->imageWidth,2);
fread((char*)&pf->imageWidth,1,2,ifs);
//ifs.read((char*)&pf->imageHeight,2);
fread((char*)&pf->imageHeight,1,2,ifs);
//ifs.read((char*)&bp,1);
fread((char*)&bp,1,1,ifs);
if((bp&0x80) != 0)
pf->lFlag = TRUE;
if((bp&0x40) != 0)
pf->interlaceFlag = TRUE;
if((bp&0x20) != 0)
pf->sortFlag = TRUE;
pf->lSize = 1;
pf->lSize <<= ((bp&0x07)+1);
if(pf->lFlag)
{ if((pf->pColorTable = new BYTE[pf->lSize*3]) == NULL)
goto error;
//ifs.read((char*)pf->pColorTable,pf->lSize*3);
fread((char*)pf->pColorTable,pf->lSize*3,1,ifs);
}
//if(!ifs.good())
// goto error;
if(!extractData(pf,ifs))
goto error;
if(ctrlExt.active)
{ pf->ctrlExt = ctrlExt;
ctrlExt.active = FALSE;
}
pf++;
break;
}
case 0x3b:
fileEnd = TRUE;
break;
case 0x00:
break;
default:
goto error;
}
}
//ifs.seekg(pos);
fseek(ifs,pos,SEEK_SET);
return TRUE;
error:
pf = allFrames;
for(i=0;i<(int)gInfo.frames;i++)
{ if(pf->pColorTable != NULL)
{ delete[] pf->pColorTable;
pf->pColorTable = NULL;
}
if(pf->dataBuf != NULL)
{ delete[] pf->dataBuf;
pf->dataBuf = NULL;
}
}
return FALSE;
}
LPCFRAME CGif89a::getNextFrame()
{ if(inMem)
{ FRAME* p = allFrames+curIndex;
curIndex++;
if(curIndex >= gInfo.frames)
curIndex = 0;
return p;
}
else
{ BYTE be;
BOOL fileEnd = FALSE;
if(curFrame.pColorTable != NULL)
{ delete[] curFrame.pColorTable;
curFrame.pColorTable = NULL;
}
if(curFrame.dataBuf != NULL)
{ delete[] curFrame.dataBuf;
curFrame.dataBuf = NULL;
}
ZeroMemory(&curFrame,sizeof(FRAME));
while(TRUE)
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,ifs);
switch(be)
{ case 0x21:
fread((char*)&be,1,1,ifs);
switch(be)
{ case 0xf9:
while(!feof(ifs))
{ fread((char*)&be,1,1,ifs);
if(be == 0)
break;
if(be == 4)
{ ctrlExt.active = TRUE;
fread((char*)&be,1,1,ifs);
ctrlExt.disposalMethod = (be&0x1c)>>2;
if((be&0x02) != 0)
ctrlExt.userInputFlag = TRUE;
else
ctrlExt.userInputFlag = FALSE;
if((be&0x01) != 0)
ctrlExt.trsFlag = TRUE;
else
ctrlExt.trsFlag = FALSE;
fread((char*)&ctrlExt.delayTime,1,2,ifs);
fread((char*)&be,1,1,ifs);
ctrlExt.trsColorIndex = be;
}
else
fseek(ifs,be,SEEK_CUR);
}
break;
case 0xfe:
case 0x01:
case 0xff:
while(!feof(ifs))
{ fread((char*)&be,1,1,ifs);
if(be == 0)
break;
fseek(ifs,be,SEEK_CUR);
}
break;
default:
goto error;
}
break;
case 0x2c:
{ BYTE bp;
fread((char*)&curFrame.imageLPos,1,2,ifs);
fread((char*)&curFrame.imageTPos,1,2,ifs);
fread((char*)&curFrame.imageWidth,1,2,ifs);
fread((char*)&curFrame.imageHeight,1,2,ifs);
fread(&bp,1,1,ifs);
if((bp&0x80) != 0)
curFrame.lFlag = TRUE;
if((bp&0x40) != 0)
curFrame.interlaceFlag = TRUE;
if((bp&0x20) != 0)
curFrame.sortFlag = TRUE;
curFrame.lSize = 1;
curFrame.lSize <<= ((bp&0x07)+1);
if((curFrame.pColorTable = new BYTE[curFrame.lSize*3]) == NULL)
goto error;
if(curFrame.lFlag)
fread((char*)curFrame.pColorTable,1,curFrame.lSize*3,ifs);
//if(!ifs.good())
// goto error;
if(!extractData(&curFrame,ifs))
goto error;
curFrame.ctrlExt = ctrlExt;
if(ctrlExt.active == TRUE) //2005.3.5
ctrlExt.active = FALSE;
return &curFrame;
}
case 0x3b:
fseek(ifs,dataStart,SEEK_SET);//
break;
case 0x00:
break;
default:
goto error;
}
}
return &curFrame;
error:
if(curFrame.pColorTable != NULL)
{ delete[] curFrame.pColorTable;
curFrame.pColorTable = NULL;
}
if(curFrame.dataBuf != NULL)
{ delete[] curFrame.dataBuf;
curFrame.dataBuf = NULL;
}
return NULL;
}
}
BOOL CGif89a::initStrTable(STRING_TABLE_ENTRY* strTable,UINT rootSize)
{ UINT i;
unsigned char *cc;
for(i=0;i<rootSize;i++)
{ if((cc = new unsigned char[2]) == NULL)
goto error;
cc[0] = i,cc[1] = 0;
strTable[i].p = cc;
strTable[i].len = 1;
}
return TRUE;
error:
for(i=0;i<rootSize;i++)
if(strTable[i].p != NULL)
{ delete[] strTable[i].p;
strTable[i].p = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -