📄 gif89a.cpp
字号:
FRAME *pf = allFrames;
streampos pos = ftell(ifs);
int i;
fprintf(stderr, "___GIF89a getAllFrames begin\n");
while(!feof(ifs) && !fileEnd)
{
fread((char*)&be, sizeof(be), 1, ifs);
fprintf(stderr, "___GIF89a getAllFrames value =%x\n", be);
switch(be)
{
case 0x21:
{
fprintf(stderr, "___GIF89a getAllFrames begin read control info\n");
fread((char*)&be, sizeof(char), 1, ifs);
fprintf(stderr, "___GIF89a control info value =%x\n", be);
switch(be)
{
case 0xf9:
{
while(!feof(ifs))
{
fread((char*)&be, sizeof(char), 1, ifs);
if(be == 0)
break;
if(be == 4)
{
ctrlExt.active = TRUE;
fread((char*)&be, sizeof(char), 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, sizeof(char), 2, ifs);
fread((char*)&be, sizeof(char), 1, ifs);
ctrlExt.trsColorIndex = be;
}
else
fseek(ifs, be, SEEK_CUR);
}
break;
}
case 0xfe:
case 0x01:
case 0xff:
while(!feof(ifs))
{
fread((char*)&be,sizeof(char), 1, ifs);
if(be == 0)
break;
fseek(ifs, be, SEEK_CUR);
}
break;
default:
goto error;
}
break;
}
case 0x2c:
{
BYTE bp;
MYBITMAP mybmp;
fprintf(stderr, "___GIF89a getAllFrames begin read Image Descriptor\n");
fread((char*)&pf->imageLPos,sizeof(char), 2, ifs);
fread((char*)&pf->imageTPos,sizeof(char), 2, ifs);
fread((char*)&pf->imageWidth,sizeof(char), 2, ifs);
fread((char*)&pf->imageHeight,sizeof(char), 2, ifs);
fread((char*)&bp,sizeof(char), 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;
fread((char*)pf->pColorTable, sizeof(char), pf->lSize*3, ifs);
}
if(ferror(ifs))
goto error;
// if(!extractData(pf,ifs))
// goto error;
if (ReadImage(ifs, &mybmp, pf, 0) == -1)
goto error;
#ifdef _USE_NEWGAL
if (ExpandMyBitmap (hdc, &(pf->bmp), &mybmp, (RGB *)(pf->pColorTable), 0) < 0)
#else
if (ExpandMyBitmap (hdc, &mybmp, (RGB *)(pf->pColorTable), &(pf->bmp)) < 0)
#endif
{
free (mybmp.bits);
goto error;
}
free (mybmp.bits);
if(ctrlExt.active)
{
pf->ctrlExt = ctrlExt;
ctrlExt.active = FALSE;
}
pf++;
break;
}
case 0x3b:
fileEnd = TRUE;
break;
case 0x00:
break;
default:
goto error;
}
}
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;
}
memset(&curFrame, 0, sizeof(FRAME));
while(TRUE)
{
fread((char*)&be, sizeof(char), 1, ifs);
switch(be)
{
case 0x21:
{
fread((char*)&be, sizeof(char), 1, ifs);
switch(be)
{ case 0xf9:
while(!feof(ifs))
{
fread((char*)&be, sizeof(char), 1, ifs);
if(be == 0)
break;
if(be == 4)
{
ctrlExt.active = TRUE;
fread((char*)&be, sizeof(char), 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,sizeof(char), 2, ifs);
fread((char*)&be, sizeof(char), 1, ifs);
ctrlExt.trsColorIndex = be;
}
else
fseek(ifs, be, SEEK_CUR);
}
break;
case 0xfe:
case 0x01:
case 0xff:
while(!feof(ifs))
{
fread((char*)&be, sizeof(char), 1, ifs);
if(be == 0)
break;
fseek(ifs, be, SEEK_CUR);
}
break;
default:
goto error;
}
break;
}
case 0x2c:
{
BYTE bp;
fread((char*)&curFrame.imageLPos, sizeof(char), 2, ifs);
fread((char*)&curFrame.imageTPos, sizeof(char), 2, ifs);
fread((char*)&curFrame.imageWidth, sizeof(char), 2, ifs);
fread((char*)&curFrame.imageHeight, sizeof(char), 2, ifs);
fread((char*)&bp, sizeof(char), 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, sizeof(char), curFrame.lSize*3, ifs);
if(ferror(ifs))
goto error;
if(!extractData(&curFrame,ifs))
goto error;
curFrame.ctrlExt = ctrlExt;
if(ctrlExt.active == TRUE)
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;
}
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[262];
BOOL readOK = FALSE;
UINT bufLen = f->imageWidth*f->imageHeight;
if((strTable = new STRING_TABLE_ENTRY[4096]) == NULL)
return FALSE;
memset(strTable, 0, sizeof(STRING_TABLE_ENTRY)*4096);
outP = f->dataBuf = new BYTE[bufLen];
if(f->dataBuf == NULL)
{
delete[] strTable;
return FALSE;
}
fread((char*)&be,sizeof(char), 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,sizeof(char), 1, ifs);
if(be != 0)
{
fread((char*)(buf+remainInBuf),sizeof(char), be, ifs);
remainInBuf += be;
}
else
readOK = TRUE;
if(ferror(ifs))
goto error;
}
if(remainInBuf<=4)
if(remainInBuf<=0 || codeSize > (remainInBuf*8-bitIndex))
goto done;
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,sizeof(char), 1, ifs);
if(be != 0)
{
fread((char*)(buf+remainInBuf),sizeof(char), be, ifs);
remainInBuf += be;
}
else
readOK = TRUE;
if(ferror(ifs))
goto error;
}
if(remainInBuf<=4)
if(remainInBuf<=0 || codeSize > (remainInBuf*8-bitIndex))
break;
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)
{
UINT i;
FRAME* pf = allFrames;
for(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);
ifs = NULL;
}
}
}
const char* CGif89a::getVer()
{
return version;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -