📄 gif89a.cpp
字号:
#include "stdafx.h"
//#include <fstream.h>
#include <stdio.h>
#include <string.h>
#include "gif89a.h"
CGif89a::CGif89a()
{ opened = FALSE;
error = FALSE;
}
CGif89a::CGif89a(LPCTSTR fileName,BOOL inMem)
{ opened = 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|ios::nocreate);
char *name;
name=new char [lstrlen(fileName)];
//中文转换
int actuallength=0;
actuallength=WideCharToMultiByte(CP_ACP,NULL,(LPCWSTR)fileName,lstrlen(fileName),(LPSTR)name,0,NULL,NULL);
delete name;
name=new char [actuallength];
ZeroMemory(name,actuallength);
WideCharToMultiByte(CP_ACP,NULL,(LPCWSTR)fileName,lstrlen(fileName),(LPSTR)name,actuallength,NULL,NULL);
m_file=fopen(name,"rb");
delete name;
if(!m_file)//ifs)
return FALSE;
//ifs.read(cc,3);
fread(cc,3,1,m_file);
if(strncmp(cc,"GIF",3) != 0)
goto error;
//ifs.read(version,3);
fread(version,3,1,m_file);
version[3] = 0;
if(strncmp(version,"89a",3) > 0)
goto error;
//ifs.read((char*)&gInfo.scrWidth,2);
//ifs.read((char*)&gInfo.scrHeight,2);
fread((char*)&gInfo.scrWidth,2,1,m_file);
fread((char*)&gInfo.scrHeight,2,1,m_file);
if(ferror(m_file))//!ifs.good())
goto error;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,m_file);
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,m_file);
gInfo.BKColorIdx = be;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,m_file);
gInfo.pixelAspectRatio = be;
if(ferror(m_file))//!ifs.good())
goto error;
if(gInfo.gFlag)
{ //ifs.read((char*)gColorTable,gInfo.gSize*3);
fread((char*)gColorTable,gInfo.gSize*3,1,m_file);
gInfo.gColorTable = gColorTable;
}
else
gInfo.gColorTable = NULL;
//dataStart = ifs.tellg();
fgetpos(m_file,&dataStart);
if((gInfo.frames = checkFrames(m_file//ifs
)) == 0)
goto error;
if(inMem)
{ if((allFrames = new FRAME[gInfo.frames]) == NULL)
goto error;
ZeroMemory(allFrames,sizeof(FRAME)*gInfo.frames);
if(!getAllFrames(m_file//ifs
))
{ delete[] allFrames;
allFrames = NULL;
goto error;
}
//ifs.close();
fclose(m_file);
}
opened = TRUE;
return TRUE;
error:
//ifs.close();
fclose(m_file);
return FALSE;
}
UINT CGif89a::checkFrames(FILE *file)//ifstream& ifs)
{ BYTE be;
BOOL fileEnd = FALSE;
UINT frames=0;
//streampos pos = ifs.tellg();
__int64 pos;
fgetpos(m_file,&pos);
while(!feof(file)//ifs.eof()
&& !fileEnd)
{
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
switch(be)
{ case 0x21:
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
switch(be)
{ case 0xf9:
case 0xfe:
case 0x01:
case 0xff:
while(!feof(file))//ifs.eof())
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
if(be == 0)
break;
//ifs.seekg(be,ios::cur);
fseek(file,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(file,8,SEEK_CUR);
//ifs.read((char*)&bp,1);
fread((char*)&bp,1,1,file);
if((bp&0x80) != 0)
lFlag = TRUE;
lSize <<= ((bp&0x07)+1);
if(lFlag)
{
//ifs.seekg(lSize*3,ios::cur);
fseek(file,lSize*3,SEEK_CUR);
}
if(ferror(file))//!ifs.good())
return 0;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
while(!feof(file))//ifs.eof())
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
if(be == 0)
break;
//ifs.seekg(be,ios::cur);
fseek(file,be,SEEK_CUR);
}
break;
}
case 0x3b:
fileEnd = TRUE;
break;
case 0x00:
break;
default:
return 0;
}
}
//ifs.seekg(pos);
fseek(file,pos,SEEK_SET);
return frames;
}
BOOL CGif89a::getAllFrames(FILE *file)//ifstream& ifs)
{ BYTE be;
BOOL fileEnd = FALSE;
FRAME *pf = allFrames;
//streampos pos = ifs.tellg();
__int64 pos;
fgetpos(m_file,&pos);
int i;
while(!feof(file)//ifs.eof()
&& !fileEnd)
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
switch(be)
{ case 0x21:
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
switch(be)
{ case 0xf9:
while(!feof(file))//ifs.eof())
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
if(be == 0)
break;
if(be == 4)
{ ctrlExt.active = TRUE;
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
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,2,1,file);
//ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
ctrlExt.trsColorIndex = be;
}
else
{
//ifs.seekg(be,ios::cur);
fseek(file,be,SEEK_CUR);
}
}
break;
case 0xfe:
case 0x01:
case 0xff:
while(!feof(file))//ifs.eof())
{ //ifs.read((char*)&be,1);
fread((char*)&be,1,1,file);
if(be == 0)
break;
//ifs.seekg(be,ios::cur);
fseek(file,be,SEEK_CUR);
}
break;
default:
goto error;
}
break;
case 0x2c:
{ BYTE bp;
//ifs.read((char*)&pf->imageLPos,2);
//ifs.read((char*)&pf->imageTPos,2);
//ifs.read((char*)&pf->imageWidth,2);
//ifs.read((char*)&pf->imageHeight,2);
//ifs.read((char*)&bp,1);
fread((char*)&pf->imageLPos,2,1,file);
fread((char*)&pf->imageTPos,2,1,file);
fread((char*)&pf->imageWidth,2,1,file);
fread((char*)&pf->imageHeight,2,1,file);
fread((char*)&bp,1,1,file);
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,file);
}
if(ferror(file))//!ifs.good())
goto error;
if(!extractData(pf,file))//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(m_file,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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -