📄 gif.cpp
字号:
#include <stdafx.h>
#include "gif89a.h"
#include "gif.h"
LPCGLOBAL_INFO gi;
LPFRAME fm;
BYTE *prevBits;
//将颜色表转换成调色板
int get_palette(RGBQUAD *lpPalette,BYTE *lpColorTable,int size)
{
DWORD *p=(DWORD*)lpPalette; BYTE *q=lpColorTable;
while (size--) {*p++=RGB(*(q+2),*(q+1),*q);q+=3;}
return sizeof(RGBQUAD)*256;
}
//对当前帧进行交错处理
void interlace()
{
if (!fm->interlaceFlag) return;
int w=fm->imageWidth,h=fm->imageHeight,i;
BYTE *dest,*p,*q; dest=new BYTE[w*h];
q=fm->dataBuf;
for (i=0;i<h;i+=8) {p=dest+i*w; memcpy(p,q,w); q+=w;}
for (i=4;i<h;i+=8) {p=dest+i*w; memcpy(p,q,w); q+=w;}
for (i=2;i<h;i+=4) {p=dest+i*w; memcpy(p,q,w); q+=w;}
for (i=1;i<h;i+=2) {p=dest+i*w; memcpy(p,q,w); q+=w;}
delete []fm->dataBuf;
fm->dataBuf=dest;
fm->interlaceFlag=FALSE;
}
//颜色复制函数;不复制前景色
void copycolor(BYTE *p1,BYTE *p2,int len)
{
while (len--){if(*p2!=fm->ctrlExt.trsColorIndex) *p1=*p2; p1++;p2++;}
}
//取得当前帧的图像位数据
int get_bits(BYTE *lpBits)
{
BYTE *p,*q;
int bpl=(gi->scrWidth*8+31)/32*4; //bytes per line
int i,w=fm->imageWidth,h=fm->imageHeight;
if ((w<gi->scrWidth||h<gi->scrHeight)&&prevBits)
memcpy(lpBits,prevBits,bpl*gi->scrHeight);
p=lpBits+(gi->scrHeight-1-fm->imageTPos)*bpl+fm->imageLPos;
q=(BYTE*)(fm->dataBuf);
if (!fm->ctrlExt.trsFlag||!prevBits) //没有透明色或者是第一帧
for (i=0;i<h;i++) {memcpy(p,q,w); p-=bpl;q+=w;}
else
for (i=0;i<h;i++) {copycolor(p,q,w); p-=bpl;q+=w;}
return bpl*gi->scrHeight;
}
HANDLE LoadGif(LPCTSTR fn)
{
CGif89a gif(fn,FALSE); if (!gif) return 0;
int i,len,w,h,bpl,frames;
HANDLE hResDyn;
BYTE *lpResDyn,*lpBits;
RESDYNDATAHEADER *lpHead;
DISPLAYFRAMEINFO *lpDisp;
STOREFRAMEINFO *lpStore;
gi=gif.getGlobalInfo();
frames=gi->frames;
w=gi->scrWidth; h=gi->scrHeight;
bpl=(w*8+31)/32*4;
len=sizeof(RESDYNDATAHEADER)
+sizeof(DISPLAYFRAMEINFO)*frames
+sizeof(STOREFRAMEINFO)*frames
+sizeof(RGBQUAD)*256;
len+=(sizeof(RGBQUAD)*256+bpl*h)*frames;
hResDyn=GlobalAlloc(GHND,len);
if (!hResDyn) return 0;
lpResDyn=(BYTE*)GlobalLock(hResDyn);
lpHead=(RESDYNDATAHEADER*)lpResDyn;
lpHead->ContentSize=len;
lpHead->Width=w;
lpHead->Height=h;
lpHead->BitCount=8;
lpHead->DisplayFrameQuantity=frames;
lpHead->StroeFrameQuantity=frames;
lpDisp=(DISPLAYFRAMEINFO*)(lpResDyn+sizeof(RESDYNDATAHEADER));
lpStore=(STOREFRAMEINFO*)((BYTE*)lpDisp+sizeof(DISPLAYFRAMEINFO)*frames);
lpBits=(BYTE*)lpStore+sizeof(STOREFRAMEINFO)*frames;
len=0;
if (gi->gFlag)
len=get_palette((RGBQUAD*)lpBits,gi->gColorTable,gi->gSize);
lpBits+=len; prevBits=NULL;
for(i=0;i<frames;i++)
{
fm=(LPFRAME)gif.getNextFrame();
if (!fm) goto error;
lpDisp->StoreFrame=i+1;
lpDisp->DelayTime=fm->ctrlExt.delayTime*10;
lpStore->Width=w;
lpStore->Height=h;
lpStore->BitCount=8;
lpStore->LocalPalette=fm->lFlag;
lpStore->XorFlag=0;
lpStore->Reserved=0;
lpStore->DataOfset=lpBits-lpResDyn;
len=0;
if (fm->lFlag)
len=get_palette((RGBQUAD*)lpBits,fm->pColorTable,fm->lSize);
lpBits+=len;
if (fm->interlaceFlag) interlace();
len=get_bits(lpBits);
prevBits=lpBits; //记下前一帧
lpBits+=len;
lpDisp++;lpStore++;
}
len=lpBits-lpResDyn;
if (lpHead->ContentSize>len) lpHead->ContentSize=len;
gif.close();
GlobalUnlock(hResDyn);
hResDyn=GlobalReAlloc(hResDyn,len,GMEM_MOVEABLE);
return hResDyn;
error:
gif.close();
GlobalUnlock(hResDyn);
GlobalFree(hResDyn);
return 0;
}
int SaveGif(LPCTSTR fn,HANDLE hResDyn)
{
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -