VC调用giflib(2):EGifOpen、DGifOpen用法
作者:马健
邮箱:stronghorse_mj@hotmail.com
主页:http://www.comicer.com/stronghorse
发布:2020.03.14
早期版本的giflib对GIF编码、解码均只提供针对文件的接口,如解码的DGifOpenFileName、DGifOpenFileHandle函数。从v5开始增加了EGifOpen、DGifOpen函数,可以更灵活地操作GIF文件,如解码内存中的GIF文件、在内存中编码GIF文件,或打开Unicode文件名的文件。
giflib官方文档对这两个新增接口说得含含糊糊,网上也有人在问究竟应该怎么用,我也是绕了一下才搞清楚,所以在这里记录一下。
这两个接口的核心思想是,把读、写操作变成函数指针,具体是在内存还是在文件中读、写,完全看函数指针所指的函数是怎么实现的。dgif_lib.c中的InternalRead函数、egif_lib.c中的InternalWrite函数就提供了读、写函数的例子,看懂了其中针对FILE*的操作,即可在此基础上写出自己的读、写函数。
例如,如果想解码内存缓冲区中的GIF文件,则可以这样写代码:
struct GifData {
const unsigned char* m_lpBuffer;
size_t m_nBufferSize;
size_t m_nPosition;
};
// copied from CMemFile::Read
int InternalRead_Mem(GifFileType *gif, GifByteType *buf, int len) {
if (len == 0)
return 0;
GifData* pData = (GifData*)gif->UserData;
if (pData->m_nPosition > pData->m_nBufferSize)
return 0;
UINT nRead;
if (pData->m_nPosition + len > pData->m_nBufferSize || pData->m_nPosition + len < pData->m_nPosition)
nRead = (UINT)(pData->m_nBufferSize - pData->m_nPosition);
else
nRead = len;
memcpy((BYTE*)buf, (BYTE*)pData->m_lpBuffer + pData->m_nPosition, nRead);
pData->m_nPosition += nRead;
return nRead;
}
// 解码内存缓冲区中的GIF文件,文件首地址pBuffer,文件长度dwLen,结果存入pImage
BOOL LoadGifFromBuffer(BYTE* pBuffer, CxImage* pImage, DWORD dwLen)
{
// DGifOpen要的数据结构
GifData data;
memset(&data, 0, sizeof(data));
data.m_lpBuffer = pBuffer;
data.m_nBufferSize = dwLen;
// 打开GIF文件
GifFileType* gif = DGifOpen(&data, InternalRead_Mem, NULL);
……
}
如果基于MFC的CFile类,则可以一次性解决Unicode文件名和在内存中对GIF文件进行操作的问题,如下面的代码:
// 写GIF文件内容到CFile
int InternalWrite_CFile(GifFileType *gif, const GifByteType *buf, int len) {
CFile* pData = (CFile*)gif->UserData;
pData->Write(buf, len);
return len;
}
// 生成GIF文件,pszTgtPath是目标路径
BOOL MakeGif(LPCTSTR pszTgtPath, ……)
{
// 打开输出的 GIF 文件
CFile fileOut;
GifFileType* GifFile;
if (!fileOut.Open(pszTgtPath, CFile::modeCreate|CFile::modeWrite))
return FALSE;
if ((GifFile = EGifOpen(&fileOut, InternalWrite_CFile, NULL)) == NULL)
return FALSE;
……
}
如果在上面的MakeGif函数里,把CFile换成CMemFile,使用同样的InternalWrite_CFile函数,则可以实现在内存里生成GIF文件。

浙公网安备 33010602011771号