| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- #include "Stdafx.h"
- #include <OLECtl.h>
- #include "GIFImage.h"
- //////////////////////////////////////////////////////////////////////////
- //构造函数
- CGIFImage::CGIFImage()
- {
- //设置变量
- m_wImageWidth=0;
- m_wImageHeight=0;
- m_nCurrentFrame=0;
- m_crBackGroundColor=RGB(255,255,255);
- return;
- }
- //析构函数
- CGIFImage::~CGIFImage()
- {
- //释放图像
- DestroyImage();
- return;
- }
- //加载动画
- bool CGIFImage::LoadFromFile(LPCTSTR pszFileName)
- {
- //效验参数
- ASSERT(pszFileName!=NULL);
- if (pszFileName==NULL) return false;
- //释放图像
- DestroyImage();
- //打开文件
- CFile GIFFile;
- if (GIFFile.Open(pszFileName,CFile::modeRead|CFile::shareDenyWrite)==FALSE)
- {
- ASSERT(FALSE);
- return false;
- }
- //创建内存
- DWORD dwFileSize=(DWORD)GIFFile.GetLength();
- BYTE * pcbData=(BYTE *)GlobalAlloc(GMEM_FIXED,dwFileSize);
- //效验结果
- ASSERT(pcbData!=NULL);
- if (pcbData==NULL) return false;
-
- //读取文件
- GIFFile.Read(pcbData,dwFileSize);
- GIFFile.Close();
- //加载动画
- bool bSuccess=LoadFromMemroy(pcbData,dwFileSize);
- //释放内存
- GlobalFree(pcbData);
- return bSuccess;
- }
- //加载动画
- bool CGIFImage::LoadFromMemroy(BYTE * pcbData, LONG lDataSize)
- {
- //效验大小
- ASSERT(pcbData!=NULL);
- ASSERT(lDataSize>=sizeof(tagGIFHeader));
- if ((pcbData==NULL)||(lDataSize<sizeof(tagGIFHeader))) return false;
- //释放图像
- DestroyImage();
- //变量定义
- tagImageDataInfo ImageDataInfo;
- ZeroMemory(&ImageDataInfo,sizeof(ImageDataInfo));
- //设置变量
- ImageDataInfo.lDataSize=lDataSize;
- ImageDataInfo.cbImageDataBuffer=pcbData;
- //判断文件
- tagGIFHeader * pGIFHeader=(tagGIFHeader *)pcbData;
- if (memcmp(&pGIFHeader->cbSignature,"GIF",3)!= 0) return false;
- if ((memcmp(&pGIFHeader->cbVersion,"87a",3)!= 0)&&(memcmp(&pGIFHeader->cbVersion,"89a",3)!= 0)) return false;
- //逻辑屏幕
- tagGIFLSDescriptor * pGIFLSDescriptor=(tagGIFLSDescriptor *)(pcbData+sizeof(tagGIFHeader));
- if (GetPackedValue(pGIFLSDescriptor,LSD_PACKED_GLOBALCT)==1)
- {
- ImageDataInfo.lColorTableSize=3*(1<<(GetPackedValue(pGIFLSDescriptor,LSD_PACKED_GLOBALCTSIZE)+1));
- BYTE * pcbBkColor=pcbData+sizeof(tagGIFHeader)+sizeof(tagGIFLSDescriptor)+3*pGIFLSDescriptor->cbBkIndex;
- m_crBackGroundColor=RGB(pcbBkColor[0],pcbBkColor[1],pcbBkColor[2]);
- };
- //设置变量
- tagGIFFrameInfo GIFFrameInfo;
- enGIFBlockTypes GIFBlockTypes;
- m_GIFFrameInfoArray.RemoveAll();
- m_wImageWidth=pGIFLSDescriptor->wWidth;
- m_wImageHeight=pGIFLSDescriptor->wHeight;
- ImageDataInfo.lCurentPos=sizeof(tagGIFHeader)+sizeof(tagGIFLSDescriptor)+ImageDataInfo.lColorTableSize;
- //生成图帧
- do
- {
- //获取信息
- GIFBlockTypes=GetCurrentBlockType(ImageDataInfo);
- if ((GIFBlockTypes==BLOCK_UNKNOWN)||(GIFBlockTypes==BLOCK_TRAILER)) break;
- //变量定义
- LONG lStartPos=ImageDataInfo.lCurentPos;
- LONG lBlockSize=GetCurrentBlockSize(ImageDataInfo);
- //图形控制
- if (GIFBlockTypes==BLOCK_CONTROLEXT)
- {
- //变量定义
- tagGIFControlExt * pGIFControlExt=(tagGIFControlExt *)(pcbData+ImageDataInfo.lCurentPos);
- //获取信息
- GIFFrameInfo.nDelay=pGIFControlExt->wDelayTime;
- GIFFrameInfo.nDisposal=GetPackedValue(pGIFControlExt,GCX_PACKED_DISPOSAL);
- do
- {
- //切换区块
- if (SwitchNextBlock(ImageDataInfo)==false) return false;
- //获取类型
- GIFBlockTypes=GetCurrentBlockType(ImageDataInfo);
- if ((GIFBlockTypes==BLOCK_UNKNOWN)||(GIFBlockTypes==BLOCK_TRAILER)) return false;
- //类型判断
- lBlockSize+=GetCurrentBlockSize(ImageDataInfo);
- if ((GIFBlockTypes==BLOCK_IMAGE)||(GIFBlockTypes==BLOCK_PLAINTEXT)) break;
- } while (true);
- }
- else
- {
- GIFFrameInfo.nDisposal=0;
- GIFFrameInfo.nDelay=0xFFFF;
- }
- //图形类型
- if (GIFBlockTypes==BLOCK_IMAGE)
- {
- //变量定义
- tagGIFImageDescriptor * pGIFImageDescriptor=(tagGIFImageDescriptor *)(pcbData+ImageDataInfo.lCurentPos);
- //获取信息
- GIFFrameInfo.wImageWidth=pGIFImageDescriptor->wWidth;
- GIFFrameInfo.wImageHeight=pGIFImageDescriptor->wHeight;
- GIFFrameInfo.wXExcursion=pGIFImageDescriptor->wXExcursion;
- GIFFrameInfo.wYExcursion=pGIFImageDescriptor->wYExcursion;
- //申请内存
- LONG lAllocSize=sizeof(tagGIFHeader)+sizeof(tagGIFLSDescriptor)+ImageDataInfo.lColorTableSize+lBlockSize+1;
- BYTE * pcbGlobal=(BYTE *)GlobalAlloc(GMEM_FIXED,lAllocSize);
- if (pcbGlobal==NULL) break;
- //拷贝内存
- LONG lOffset=0L;
- CopyMemory(pcbGlobal,pcbData,sizeof(tagGIFHeader)+sizeof(tagGIFLSDescriptor)+ImageDataInfo.lColorTableSize);
- lOffset+=sizeof(tagGIFHeader)+sizeof(tagGIFLSDescriptor)+ImageDataInfo.lColorTableSize;
- CopyMemory(pcbGlobal+lOffset,pcbData+lStartPos,lBlockSize);
- lOffset+=lBlockSize;
- pcbGlobal[lOffset++]=0x3B;
- //创建图像
- IStream * pIStream=NULL;
- if (CreateStreamOnHGlobal(pcbGlobal,TRUE,&pIStream)!=S_OK)
- {
- ASSERT(FALSE);
- GlobalFree(pcbGlobal);
- break;
- };
- //加载图片
- if (OleLoadPicture(pIStream,lOffset,FALSE,IID_IPicture,(VOID * *)&GIFFrameInfo.pIFramePicture)!=S_OK)
- {
- ASSERT(FALSE);
- SafeRelease(pIStream);
- break;
- };
- //释放资源
- SafeRelease(pIStream);
- //加入图帧
- m_GIFFrameInfoArray.Add(GIFFrameInfo);
- }
- //切换区块
- if (SwitchNextBlock(ImageDataInfo)==false) break;
- } while (true);
- return true;
- }
- //加载动画
- bool CGIFImage::LoadFromResource(LPCTSTR pszResourceName, LPCTSTR pszResourceType)
- {
- //效验参数
- ASSERT(pszResourceName!=NULL);
- ASSERT(pszResourceType!=NULL);
- if ((pszResourceName==NULL)||(pszResourceType==NULL)) return false;
- //释放图像
- DestroyImage();
- //获取资源
- HRSRC hPicture=FindResource(AfxGetResourceHandle(),pszResourceName,pszResourceType);
- if (hPicture==NULL) return false;
- HGLOBAL hResData=LoadResource(AfxGetResourceHandle(),hPicture);
- if (hResData=NULL) return false;
- //创建内存
- DWORD dwResourceSize=SizeofResource(AfxGetResourceHandle(),hPicture);
- BYTE * pcbData=(BYTE *)GlobalAlloc(GMEM_FIXED,dwResourceSize);
- if (pcbData==NULL)
- {
- FreeResource(hResData);
- return false;
- }
- //锁定资源
- BYTE * pcbSrc=(BYTE *)LockResource(hResData);
- if (pcbSrc==NULL)
- {
- GlobalFree(pcbData);
- FreeResource(hResData);
- return false;
- }
- //拷贝数据
- CopyMemory(pcbData,pcbSrc,dwResourceSize);
- FreeResource(hResData);
- //加载动画
- bool bSuccess=LoadFromMemroy(pcbData,dwResourceSize);
- //释放内存
- GlobalFree(pcbData);
- return bSuccess;
- }
- //是否加载
- bool CGIFImage::IsNull()
- {
- return (m_GIFFrameInfoArray.GetCount()==0);
- }
- //释放图像
- VOID CGIFImage::DestroyImage()
- {
- //设置变量
- m_wImageWidth=0;
- m_wImageHeight=0;
- m_nCurrentFrame=0;
- m_crBackGroundColor=RGB(255,255,255);
- //释放图帧
- if (m_GIFFrameInfoArray.GetCount()>0)
- {
- for (INT_PTR i=0;i<m_GIFFrameInfoArray.GetCount();i++)
- {
- //获取对象
- tagGIFFrameInfo * pGIFFrameInfo=&m_GIFFrameInfoArray[i];
- //释放接口
- SafeRelease(pGIFFrameInfo->pIFramePicture);
- }
- //删除数组
- m_GIFFrameInfoArray.RemoveAll();
- }
- return;
- }
- //当前图像
- tagGIFFrameInfo * CGIFImage::GetCurrentFrame()
- {
- //状态效验
- ASSERT(IsNull()==false);
- if (IsNull()==true) return NULL;
- return &m_GIFFrameInfoArray[m_nCurrentFrame];
- }
- //绘画图像
- VOID CGIFImage::DrawImageFrame(CDC * pDC, INT nXPos, INT nYPos)
- {
- //绘画图片
- DrawImageFrame(pDC,nXPos,nYPos,m_nCurrentFrame);
- //调整图帧
- m_nCurrentFrame=((m_nCurrentFrame+1)==m_GIFFrameInfoArray.GetCount())?0L:(m_nCurrentFrame+1L);
- return;
- }
- //绘画图像
- VOID CGIFImage::DrawImageFrame(CDC * pDC, INT nXPos, INT nYPos, INT_PTR nFrameIndex)
- {
- //获取数据
- ASSERT(nFrameIndex<m_GIFFrameInfoArray.GetCount());
- tagGIFFrameInfo * pGIFFrameInfo=&m_GIFFrameInfoArray[nFrameIndex];
- //获取大小
- OLE_XSIZE_HIMETRIC hmWidth=0L;
- OLE_YSIZE_HIMETRIC hmHeight=0L;
- pGIFFrameInfo->pIFramePicture->get_Width(&hmWidth);
- pGIFFrameInfo->pIFramePicture->get_Height(&hmHeight);
- //绘画图片
- pGIFFrameInfo->pIFramePicture->Render(pDC->m_hDC,nXPos+pGIFFrameInfo->wXExcursion,nYPos+pGIFFrameInfo->wYExcursion,
- pGIFFrameInfo->wImageWidth,pGIFFrameInfo->wImageHeight,0,hmHeight,hmWidth,-hmHeight,NULL);
- return;
- }
- //区块长度
- LONG CGIFImage::GetCurrentBlockSize(tagImageDataInfo & ImageDataInfo)
- {
- enGIFBlockTypes GIFBlockTypes=GetCurrentBlockType(ImageDataInfo);
- switch (GIFBlockTypes)
- {
- case BLOCK_UNKNOWN: { return -1; }
- case BLOCK_TRAILER: { return 1; }
- case BLOCK_APPEXT:
- {
- LONG lSubSize=GetSubBlockSize(ImageDataInfo,ImageDataInfo.lCurentPos+sizeof(tagGIFAppExtension));
- return sizeof(tagGIFAppExtension)+lSubSize;
- }
- case BLOCK_COMMEXT:
- {
- LONG lSubSize=GetSubBlockSize(ImageDataInfo,ImageDataInfo.lCurentPos+sizeof(tagGIFCommentExt));
- return sizeof(tagGIFCommentExt)+lSubSize;
- }
- case BLOCK_CONTROLEXT:
- {
- return sizeof(tagGIFControlExt);
- }
- case BLOCK_PLAINTEXT:
- {
- LONG lSubSize=GetSubBlockSize(ImageDataInfo,ImageDataInfo.lCurentPos+sizeof(tagGIFPlainTextExt));
- return sizeof(tagGIFPlainTextExt)+lSubSize;
- }
- case BLOCK_IMAGE:
- {
- INT nLCTSize=0;
- tagGIFImageDescriptor * pGIFImageDescriptor=(tagGIFImageDescriptor *)(ImageDataInfo.cbImageDataBuffer+ImageDataInfo.lCurentPos);
- if (GetPackedValue(pGIFImageDescriptor,ID_PACKED_LOCALCT)==1)
- {
- nLCTSize=(1<<(GetPackedValue(pGIFImageDescriptor,ID_PACKED_LOCALCTSIZE)+1))*3;
- }
- LONG lSubSize=GetSubBlockSize(ImageDataInfo,ImageDataInfo.lCurentPos+sizeof(tagGIFImageDescriptor)+nLCTSize+1);
- return sizeof(tagGIFImageDescriptor)+nLCTSize+lSubSize+1;
- }
- };
- return 0;
- }
- //获取类型
- enGIFBlockTypes CGIFImage::GetCurrentBlockType(tagImageDataInfo & ImageDataInfo)
- {
- switch (ImageDataInfo.cbImageDataBuffer[ImageDataInfo.lCurentPos])
- {
- case 0x21:
- {
- switch (ImageDataInfo.cbImageDataBuffer[ImageDataInfo.lCurentPos+1])
- {
- case 0x01: { return BLOCK_PLAINTEXT; }
- case 0xF9: { return BLOCK_CONTROLEXT; }
- case 0xFE: { return BLOCK_COMMEXT; }
- case 0xFF: { return BLOCK_APPEXT; }
- };
- break;
- }
- case 0x3B: { return BLOCK_TRAILER; }
- case 0x2C: { return BLOCK_IMAGE; }
- }
- return BLOCK_UNKNOWN;
- }
- //区块长度
- LONG CGIFImage::GetSubBlockSize(tagImageDataInfo & ImageDataInfo,LONG lBlockPos)
- {
- LONG lBlockLength=0;
- while (ImageDataInfo.cbImageDataBuffer[lBlockPos]!=0)
- {
- lBlockLength+=ImageDataInfo.cbImageDataBuffer[lBlockPos]+1;
- lBlockPos+=ImageDataInfo.cbImageDataBuffer[lBlockPos]+1;
- };
- return lBlockLength+1;
- }
- //切换区块
- bool CGIFImage::SwitchNextBlock(tagImageDataInfo & ImageDataInfo)
- {
- LONG lBlockSize=GetCurrentBlockSize(ImageDataInfo);
- if ((lBlockSize<=0)||((ImageDataInfo.lCurentPos+lBlockSize)>ImageDataInfo.lDataSize)) return false;
- ImageDataInfo.lCurentPos+=lBlockSize;
- return true;
- }
- //获取数值
- INT CGIFImage::GetPackedValue(const tagGIFControlExt * pGIFControlExt, enum enControlExtValues Value)
- {
- switch (Value)
- {
- case GCX_PACKED_DISPOSAL: //处置方法
- {
- return (pGIFControlExt->cbPacked&28)>>2;
- }
- case GCX_PACKED_USERINPUT: //输入标志
- {
- return (pGIFControlExt->cbPacked&2)>>1;
- }
- case GCX_PACKED_TRANSPCOLOR: //透明标志
- {
- return pGIFControlExt->cbPacked&1;
- }
- };
- ASSERT(FALSE);
- return 0;
- }
- //获取数值
- INT CGIFImage::GetPackedValue(const tagGIFImageDescriptor * pGIFImageDescriptor, enum enIDPackedValues Value)
- {
- switch (Value)
- {
- case ID_PACKED_LOCALCT: //颜色标志
- {
- return pGIFImageDescriptor->cbPacked>>7;
- }
- case ID_PACKED_INTERLACE: //交织标志
- {
- return (pGIFImageDescriptor->cbPacked&0x40)>>6;
- }
- case ID_PACKED_SORT: //分类标志
- {
- return (pGIFImageDescriptor->cbPacked&0x20)>>5;
- }
- case ID_PACKED_LOCALCTSIZE: //颜色大小
- {
- return pGIFImageDescriptor->cbPacked&7;
- }
- };
- ASSERT(FALSE);
- return 0;
- }
- //获取数值
- INT CGIFImage::GetPackedValue(const tagGIFLSDescriptor * pGIFLSDescriptor, enum enLSDPackedValues Value)
- {
- switch (Value)
- {
- case LSD_PACKED_GLOBALCT: //颜色标志
- {
- return pGIFLSDescriptor->cbPacked>>7;
- }
- case LSD_PACKED_CRESOLUTION: //颜色深度
- {
- return ((pGIFLSDescriptor->cbPacked&0x70)>>4)+1;
- }
- case LSD_PACKED_SORT: //分类标志
- {
- return (pGIFLSDescriptor->cbPacked&8)>>3;
- }
- case LSD_PACKED_GLOBALCTSIZE: //全局颜色
- {
- return pGIFLSDescriptor->cbPacked & 0x07;
- }
- };
- ASSERT(FALSE);
- return 0;
- }
- //////////////////////////////////////////////////////////////////////////
|