⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gifdeclib.c

📁 GIF动画解码算法
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	
	for(i=0;i<height;i++)
	{
		for(j=0;j<width;j++)
		{	
			curX = LeftX + offX + j;
			curY = TopY + offY + i;
			if(ClockWise){
				temp = nWidth + LeftX-1 - curY;
				curY = curX;
				curX = temp;
			}
			if(curX<LeftX || curX>=nWidth+LeftX|| curY<TopY || curY>=nHeight+TopY){
				pRGB += 3;
				continue;				
			}
			if(once){
				curR.left = curX;
				curR.top = curY;
				curR.width = width;
				curR.height = height;
				once = 0;
			}
/*			if ((curY % 2) == 0)
			{
				switch( curX % 3 )
				{
					case 0:
						tranRGB = tG;
						break ;
					case 1:
						tranRGB = tB;
						break ; 				
					case 2:
						tranRGB = tR;
						break ; 				
				}		
			}
			else
			{
				switch( curX % 3 )
				{
					case 0:
						tranRGB = tR;
						break ; 				
					case 1:
						tranRGB = tG;
						break ; 				
					case 2:
						tranRGB = tB;
						break ; 				
				}				
			}	*/
//			thisRGB = *pRGB;				
			if(pImage->m_Frame.m_TransparentFlag == 1)
			{
				switch(lastDisposal){
					case 0: 			// unspecified
//						FillDot(curX,curY,thisRGB>>4);
						PutPixel(curX,curY,*pRGB,*(pRGB+1),*(pRGB+2));
						break;
					case 1: 			// do not dispose
//						if(thisRGB != tranRGB)
//							FillDot(curX,curY, thisRGB>>4);
						if(*pRGB!=tR && *(pRGB+1)!=tG && *(pRGB+2)!=tB)
							PutPixel(curX,curY,*pRGB,*(pRGB+1),*(pRGB+2));							
						break;
					case 2: 			// restore to background
						if(!RestoreTag){							
							Large_RestoreBckgrnd(pImage,curFrame,ClockWise,&lastR,&curR,LeftX,TopY,nWidth,nHeight);
							RestoreTag = 1;
						}
//						FillDot( curX,curY, thisRGB>>4);
						PutPixel(curX,curY,*pRGB,*(pRGB+1),*(pRGB+2));
						break;
					case 3: 			// restore to previous
//						Large_SubDrawFrameRGB(pImage,0,ClockWise,deltaH,deltaW,lastR.left,lastR.top,nWidth,nHeight);
						if (*pRGB!=tR && *(pRGB+1)!=tG && *(pRGB+2)!=tB){
							PutPixel(curX,curY,*pRGB,*(pRGB+1),*(pRGB+2));
						}
						break; 
					default:
						PutPixel(curX,curY,*pRGB,*(pRGB+1),*(pRGB+2));
						break;
				}
			}
			else
			{
				PutPixel(curX,curY,*pRGB,*(pRGB+1),*(pRGB+2));
			}
			pRGB += 3;
		}
		if(j>=width/* && *pisResized */)
			pRGB += BYTEWIDTH(width,24) -width*3;
	}
	StnRefresh();
	lastR.left = curR.left;
	lastR.top = curR.top;
	lastR.width = curR.width;
	lastR.height = curR.height;
	lastDisposal = pImage->m_Frame.m_nDisposal;
	return TRUE;	
}
void DestroyImage(TImage *pImage)
{
	int i;
	for(i = 0;i < pImage->m_nFrameCount;i++){
		NU_Deallocate_Memory(pImage->m_arrFrames[i].m_pRGB);
	}
	NU_Deallocate_Memory(pImage->m_arrFrames);
}
BOOL Large_GIFFrameAdjust(TImage *pImage,
						int curFrame,
						int nWidth,
						int nHeight,
						BOOL *pisResized)
{
	static float	coeff;
	static int		diff;
	static BOOL 	noSkip;
	int 			i,uiOutWidthBytes;
	int 			oldWidth,oldHeight;
	float			coeff1,coeff2,picWidth,picHeight,newWidth,newHeight;
	int 			iNewWidth,iNewHeight;
	int 			dwNewBmpSize;
	BYTE		*pData;
	BYTE		*pNew;
	int 			ImgMaxSide,ImgMinSide,ScrMaxSide,ScrMinSide;
	char			skip=0;

	if(curFrame == 0){
		noSkip = FALSE;
		oldWidth = pImage->m_PictureSize.cx;
		oldHeight = pImage->m_PictureSize.cy;
		ImgMaxSide = oldWidth > oldHeight ? oldWidth : oldHeight;
		ImgMinSide = oldWidth < oldHeight ? oldWidth : oldHeight;
		ScrMaxSide = nWidth > nHeight ? nWidth : nHeight;
		ScrMinSide = nWidth < nHeight ? nWidth : nHeight;

		if((ImgMaxSide>ScrMaxSide || ImgMinSide>ScrMinSide) && (pImage->m_Frame.m_TransparentFlag >0 && pImage->m_Frame.m_nDisposal ==1)){
			noSkip = FALSE;
			*pisResized = FALSE;
			return TRUE;
		}

		if(ImgMaxSide>=ScrMaxSide && ImgMinSide>=ScrMinSide){			
			coeff1 = (float)ImgMaxSide / (float)ScrMaxSide;
			coeff2 = (float)ImgMinSide / (float)ScrMinSide;
			coeff = coeff1>coeff2 ? coeff1 : coeff2;
			diff = 1;			
			pImage->m_PictureSize.cx = (int)((float)oldWidth / coeff);
			pImage->m_PictureSize.cy = (int)((float)oldHeight / coeff);
			noSkip = TRUE;
		}
		else if(ImgMaxSide<=ScrMaxSide && ImgMinSide<=ScrMinSide){		
			coeff1 = (float)(ScrMaxSide) /(float)(ImgMaxSide);
			coeff2 = (float)(ScrMinSide) / (float)(ImgMinSide);
			coeff = coeff1<coeff2 ? coeff1 : coeff2;
			diff = 2;
			pImage->m_PictureSize.cx = (int)((float)oldWidth * coeff);
			pImage->m_PictureSize.cy = (int)((float)oldHeight * coeff);
			noSkip = TRUE;
		}
		else if(ImgMaxSide>=ScrMaxSide && ImgMinSide<=ScrMinSide){
			coeff = (float)ImgMaxSide / (float)ScrMaxSide;
			diff = 1;
			pImage->m_PictureSize.cx = (int)((float)oldWidth / coeff);
			pImage->m_PictureSize.cy = (int)((float)oldHeight / coeff); 		
			noSkip = TRUE;
		}
		else if(ImgMinSide>=ScrMinSide && ImgMaxSide<=ScrMaxSide){
			coeff = (float)ImgMinSide / (float)ScrMinSide;
			diff = 1;
			pImage->m_PictureSize.cx = (int)((float)oldWidth / coeff);
			pImage->m_PictureSize.cy = (int)((float)oldHeight / coeff); 
			noSkip = TRUE;
		}
	}
	if(noSkip){
		switch(diff){
			case 1:
				pImage->m_Frame.m_imageDescriptor.m_wLeftPos = (int)((float)(pImage->m_Frame.m_imageDescriptor.m_wLeftPos / coeff));
				pImage->m_Frame.m_imageDescriptor.m_wTopPos = (int)((float)(pImage->m_Frame.m_imageDescriptor.m_wTopPos / coeff));
				oldWidth = pImage->m_Frame.m_imageDescriptor.m_wWidth;
				oldHeight = pImage->m_Frame.m_imageDescriptor.m_wHeight;
				newWidth = (float)oldWidth / coeff;
				newHeight = (float)oldHeight / coeff;
				pImage->m_Frame.m_imageDescriptor.m_wWidth = (int)newWidth;
				pImage->m_Frame.m_imageDescriptor.m_wHeight = (int)newHeight;
				break;
			case 2:
				pImage->m_Frame.m_imageDescriptor.m_wLeftPos = (int)(pImage->m_Frame.m_imageDescriptor.m_wLeftPos * coeff);
				pImage->m_Frame.m_imageDescriptor.m_wTopPos = (int)(pImage->m_Frame.m_imageDescriptor.m_wTopPos * coeff);
				oldWidth = pImage->m_Frame.m_imageDescriptor.m_wWidth;
				oldHeight = pImage->m_Frame.m_imageDescriptor.m_wHeight;
				newWidth = (float)oldWidth * coeff;
				newHeight = (float)oldHeight * coeff;
				pImage->m_Frame.m_imageDescriptor.m_wWidth = (int)newWidth;
				pImage->m_Frame.m_imageDescriptor.m_wHeight = (int)newHeight;
				break;
			defaut:
				break;
		}
		iNewWidth = (int)newWidth;
		iNewHeight = (int)newHeight;
		if(curFrame!=0 && pImage->m_Frame.m_TransparentFlag ==1 && pImage->m_Frame.m_nDisposal == 1)
			skip = 1;
		pNew = MakeDwordAlignedBuf((BYTE *)pImage->m_Frame.m_pRGB,oldWidth,oldHeight,&uiOutWidthBytes);
		if(pNew == NULL){
			return FALSE;
		}
		pData = yu_RszBmpForGIF(pNew,oldWidth,oldHeight,iNewWidth,iNewHeight,&dwNewBmpSize,skip);
		if(pData == NULL){
			NU_Deallocate_Memory(pNew);
			return FALSE;
		}
		pImage->m_Frame.m_pRGB = pData; 
		NU_Deallocate_Memory(pNew);
	}		
	return TRUE;
}

BYTE * MakeDwordAlignedBuf(BYTE *dataBuf,
								UINT widthPix,
								UINT height,
								UINT *uiOutWidthBytes) 
{
	UINT uiWidthBytes;
	DWORD dwNewsize;
	BYTE *pNew;
	UINT uiInWidthBytes; 
	UINT uiCount;
	BYTE * bpInAdd;
	BYTE * bpOutAdd;
	ULONG lInOff;
	ULONG lOutOff;

	if (dataBuf==NULL)
		return NULL;
	uiWidthBytes = WIDTHBYTES(widthPix * 24);
	dwNewsize=(DWORD)((DWORD)uiWidthBytes * (DWORD)height); 
	if(NU_SUCCESS!=NU_Allocate_Memory(&System_Memory,&pNew,dwNewsize,0))
		return NULL;
	uiInWidthBytes = widthPix * 3;
	for (uiCount=0;uiCount < height;uiCount++) {
		lInOff=uiInWidthBytes * uiCount;
		lOutOff=uiWidthBytes * uiCount;

		bpInAdd= dataBuf + lInOff;
		bpOutAdd= pNew + lOutOff;
		memcpy(bpOutAdd,bpInAdd,uiInWidthBytes);
	}
	*uiOutWidthBytes=uiWidthBytes;
	if(widthPix!=1)							// be careful of this memory deallocation
		NU_Deallocate_Memory(dataBuf);
	return pNew;
}

void RestoreBckgrnd(TImage *pImage,
						int curFrame,
						int clockWise,
						RECT *plastR,
						RECT *pcurR,
						int LeftX,
						int TopY,
						int nWidth,
						int nHeight)
{
	int tranIndex;
	int deltaW,deltaH;
	BYTE R,G,B;
	tranIndex = pImage->m_arrFrames[curFrame].m_controlExt.m_cTColorIndex;
	R = pImage->m_pRawData[pImage->m_arrFrames[curFrame].m_LCTPos + 3*tranIndex + 0]; //fill Red 
	G = pImage->m_pRawData[pImage->m_arrFrames[curFrame].m_LCTPos + 3*tranIndex + 1]; //fill Green 
	B = pImage->m_pRawData[pImage->m_arrFrames[curFrame].m_LCTPos + 3*tranIndex + 2]; //fill Blue
	
	if(pImage->m_nFrameCount==80){
		WriteRect(LeftX,TopY, nWidth, nHeight,R,G,B);
	}
	else{
		if((deltaW = pcurR->left - plastR->left)>0)
			WriteRect(plastR->left,plastR->top,deltaW,plastR->height,R,G,B);
		
		if((deltaW = plastR->left -(pcurR->left+pcurR->width)>0))
			WriteRect(pcurR->left+pcurR->width,plastR->top,deltaW,plastR->height,R,G,B);
		
		if((deltaH = pcurR->top - plastR->top)>0)
			WriteRect(plastR->left,plastR->top,plastR->width,deltaH,R,G,B);
		
		if((deltaW=(plastR->left+plastR->width)-(pcurR->left+pcurR->width))>0)
			WriteRect(pcurR->left+pcurR->width,plastR->top,deltaW,plastR->height,R,G,B);
		
		if((deltaH = (plastR->top + plastR->height) -(pcurR->top+pcurR->height))>0)
			WriteRect(plastR->left,pcurR->top+pcurR->height,plastR->width,deltaH,R,G,B);
			
		if(clockWise && (pcurR->width!= plastR->width || pcurR->height!=plastR->height))
			WriteRect(plastR->left-plastR->height,plastR->top,plastR->height,plastR->width,R,G,B);	
	}
}
void Large_RestoreBckgrnd(TImage *pImage,
								int curFrame,
								int clockWise,
								RECT *plastR,
								RECT *pcurR,
								int LeftX,
								int TopY,
								int nWidth,
								int nHeight)
{
	int tranIndex;
	int deltaW,deltaH;
	BYTE R,G,B;
	tranIndex = pImage->m_Frame.m_controlExt.m_cTColorIndex;
	R = pImage->m_pRawData[pImage->m_Frame.m_LCTPos + 3*tranIndex + 0]; //fill Red 
	G = pImage->m_pRawData[pImage->m_Frame.m_LCTPos + 3*tranIndex + 1]; //fill Green 
	B = pImage->m_pRawData[pImage->m_Frame.m_LCTPos + 3*tranIndex + 2]; //fill Blue
	
	if(pImage->m_nFrameCount==80){
		WriteRect(LeftX,TopY, nWidth, nHeight,R,G,B);
	}
	else{
		if((deltaW = pcurR->left - plastR->left)>0)
			WriteRect(plastR->left,plastR->top,deltaW,plastR->height,R,G,B);
		
		if((deltaW = plastR->left -(pcurR->left+pcurR->width)>0))
			WriteRect(pcurR->left+pcurR->width,plastR->top,deltaW,plastR->height,R,G,B);
		
		if((deltaH = pcurR->top - plastR->top)>0)
			WriteRect(plastR->left,plastR->top,plastR->width,deltaH,R,G,B);
		
		if((deltaW=(plastR->left+plastR->width)-(pcurR->left+pcurR->width))>0)
			WriteRect(pcurR->left+pcurR->width,plastR->top,deltaW,plastR->height,R,G,B);
		
		if((deltaH = (plastR->top + plastR->height) -(pcurR->top+pcurR->height))>0)
			WriteRect(plastR->left,pcurR->top+pcurR->height,plastR->width,deltaH,R,G,B);
			
		if(clockWise && (pcurR->width!= plastR->width || pcurR->height!=plastR->height))
			WriteRect(plastR->left-plastR->height,plastR->top,plastR->height,plastR->width,R,G,B);	
	}
}

void WriteRect(int left,
				int top,
				int width,
				int height,
				BYTE R,
				BYTE G,
				BYTE B)
{
	int i,j;
	int curX,curY;
	BYTE thisRGB;
	for(i=0;i<height;i++){
		for(j=0;j<width;j++){
			curX = left + j;
			curY = top + i;
/*			if ((curY % 2) == 0)
			{
				switch( curX % 3 )
				{
					case 0:
						thisRGB = G;
						break ;
					case 1:
						thisRGB = B;
			
						break ; 				
					case 2:
						thisRGB = R;
						break ; 				
				}		
			}
			else
			{
				switch( curX % 3 )
				{
					case 0:
						thisRGB = R;
						break ; 				
					case 1:
						thisRGB = G;
						break ; 				
					case 2:
						thisRGB = B;
						break ; 				
				}				
			}		
			FillDot(curX,curY,thisRGB>>4);		*/
			PutPixel(curX, curY, R, G, B);
		}
	}
}

void PutPixel(U32 curX,U32 curY,U8 R,U8 G,U8 B)
{
	U8 thisRGB;
	if ((curY % 2) == 0){
		switch( curX % 3 ){
			case 0:
				thisRGB = G; //fill Green 
				break ;
			case 1:
				thisRGB = B; //fill Blue
				break ; 				
			case 2:
				thisRGB = R; //fill Red
				break ; 				
		}		
	}
	else{
		switch( curX % 3 ){
			case 0:
				thisRGB = R; //fill Red 
				break ; 				
			case 1:
				thisRGB = G; //fill Green
				break ; 				
			case 2:
				thisRGB = B; //fill Blue
				break ; 				
		}				
	}
	FillDot(curX,curY,thisRGB>>4);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -