📄 gif89a.cpp
字号:
return FALSE;
}
BOOL CGif89a::addStrTable(STRING_TABLE_ENTRY* strTable,UINT addIdx,UINT idx,unsigned char c)
{ unsigned char *cc;
UINT l = strTable[idx].len;
if(addIdx >= 4096)
return FALSE;
if((cc = new unsigned char[l+2]) == NULL)
return FALSE;
for(UINT i=0;i<l;i++)
cc[i] = strTable[idx].p[i];
cc[l] = c;
cc[l+1] = 0;
strTable[addIdx].p = cc;
strTable[addIdx].len = strTable[idx].len +1;
return TRUE;
}
BOOL CGif89a::extractData(FRAME* f,FILE *ifs)
{ STRING_TABLE_ENTRY *strTable;
UINT codeSize,rootSize,tableIndex,codeSizeBK;
int remainInBuf = 0,i;
UINT bufIndex = 0,outIndex = 0;
UINT bitIndex = 0;
DWORD code,oldCode;
BYTE be,*outP;
BYTE buf[1024];//260];//262
BOOL readOK = FALSE;
UINT bufLen = f->imageWidth*f->imageHeight;
if((strTable = new STRING_TABLE_ENTRY[4096]) == NULL)
return FALSE;
ZeroMemory(strTable,sizeof(STRING_TABLE_ENTRY)*4096);
// memset(strTable,0x00,sizeof(STRING_TABLE_ENTRY)*4096);
outP = f->dataBuf = new BYTE[bufLen];
if(f->dataBuf == NULL)
{ delete[] strTable;
return FALSE;
}
fread((char*)&be,1,1,ifs);
codeSizeBK = codeSize = be+1;
rootSize = 1;
rootSize <<= be;
tableIndex = rootSize+2;
if(!initStrTable(strTable,rootSize))
goto error;
begin:
if(remainInBuf<=4 && !readOK)
{ for(i=0;i<remainInBuf;i++)
buf[i] = buf[bufIndex+i];
bufIndex = 0;
fread((char*)&be,1,1,ifs);
if(be != 0)
{ fread((char*)(buf+remainInBuf),1,be,ifs);
remainInBuf += be;
}
else
readOK = TRUE;
//if(!ifs.good())
// goto error;
}
if(remainInBuf<=4)
if(remainInBuf<=0 || codeSize > (remainInBuf*8-bitIndex))
goto done;
code = *((UNALIGNED DWORD*)(buf+bufIndex));
//code = (DWORD)buf[bufIndex];
code <<= 32-codeSize-bitIndex;
code >>= 32-codeSize;
bitIndex += codeSize;
bufIndex += bitIndex/8;
remainInBuf -= bitIndex/8;
bitIndex %= 8;
if(code >= rootSize+1)
goto error;
if(code == rootSize)
goto begin;
else
{ outP[outIndex++] = *strTable[code].p;
oldCode = code;
}
for(;;)
{ if(remainInBuf<=4 && !readOK)
{ for(i=0;i<remainInBuf;i++)
buf[i] = buf[bufIndex+i];
bufIndex = 0;
fread((char*)&be,1,1,ifs);
if(be != 0)
{ fread((char*)(buf+remainInBuf),1,be,ifs);
remainInBuf += be;
}
else
readOK = TRUE;
//if(!ifs.good())
// goto error;
}
if(remainInBuf<=4)
if(remainInBuf<=0 || codeSize > (remainInBuf*8-bitIndex))
break;
code = *((UNALIGNED DWORD*)(buf+bufIndex));
// code = (DWORD)buf[bufIndex];
code <<= 32-codeSize-bitIndex;
code >>= 32-codeSize;
bitIndex += codeSize;
bufIndex += bitIndex/8;
remainInBuf -= bitIndex/8;
bitIndex %= 8;
if(code == rootSize)
{ codeSize = codeSizeBK;
for(i=rootSize;i<4096;i++)
if(strTable[i].p != NULL)
{ delete strTable[i].p;
strTable[i].p = NULL;
strTable[i].len = 0;
}
tableIndex = rootSize+2;
goto begin;
}
else if(code == rootSize+1)
break;
else
{ unsigned char *p = strTable[code].p;
int l = strTable[code].len;
unsigned char c;
if(p != NULL)
{ c = *p;
if(outIndex+l <= bufLen)
for(i=0;i<l;i++)
outP[outIndex++] = *p++;
else
goto error;
if(!addStrTable(strTable,tableIndex++,oldCode,c))
goto error;
oldCode = code;
}
else
{ p = strTable[oldCode].p;
l = strTable[oldCode].len;
c = *p;
if(outIndex+l+1 <= bufLen)
{ for(i=0;i<l;i++)
outP[outIndex++] = *p++;
outP[outIndex++] = c;
}
else
goto error;
if(!addStrTable(strTable,tableIndex++,oldCode,c))
goto error;
oldCode = code;
}
if(tableIndex == (((UINT)1)<<codeSize) && codeSize != 12)
codeSize++;
}
}
done:
for(i=0;i<4096;i++)
if(strTable[i].p != NULL)
{ delete strTable[i].p;
strTable[i].p = NULL;
}
delete[] strTable;
return TRUE;
error:
for(i=0;i<4096;i++)
if(strTable[i].p != NULL)
{ delete strTable[i].p;
strTable[i].p = NULL;
}
delete[] strTable;
delete[] f->dataBuf;
f->dataBuf = NULL;
return FALSE;
}
LPCGLOBAL_INFO CGif89a::getGlobalInfo()
{ return &gInfo;
}
void CGif89a::close()
{ if(opened)
{ opened = FALSE;
if(inMem && allFrames != NULL)
{ FRAME* pf = allFrames;
for(UINT i=0;i<gInfo.frames;i++)
{ if(pf->pColorTable != NULL)
{ delete[] pf->pColorTable;
pf->pColorTable = NULL;
}
if(pf->dataBuf != NULL)
{ delete[] pf->dataBuf;
pf->dataBuf = NULL;
}
}
delete[] allFrames;
allFrames = NULL;
}
if(!inMem)
{ if(curFrame.pColorTable != NULL)
{ delete[] curFrame.pColorTable;
curFrame.pColorTable = NULL;
}
if(curFrame.dataBuf != NULL)
{ delete[] curFrame.dataBuf;
curFrame.dataBuf = NULL;
}
fclose(ifs);
}
}
}
LPCSTR CGif89a::getVer()
{ return version;
}
//
LPCFRAME CGif89a::getCurFrame()
{
//long pos=ftell(ifs);
//Reset();
//fseek(ifs,dataStart,SEEK_SET);
//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((char*)&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;
}
}
//expand
LPCFRAME CGif89a::getHeadFrame()
{ if(inMem)
{ FRAME* p = allFrames;//+curIndex;
//curIndex++;
//if(curIndex >= gInfo.frames)
// curIndex = 0;
return p;
}
else
{ //reset
fseek(ifs,dataStart,SEEK_SET);//
//
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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -