📄 gifdeclib.c
字号:
return BLOCK_PLAINTEXT;
break;
case 0xF9:
// graphic control extension
return BLOCK_CONTROLEXT;
break;
case 0xFE:
// comment extension
return BLOCK_COMMEXT;
break;
case 0xFF:
// application extension
return BLOCK_APPEXT;
break;
};
break;
case 0x3B:
// trailer
return BLOCK_TRAILER;
break;
case 0x2C:
// image data
return BLOCK_IMAGE;
break;
};
return BLOCK_UNKNOWN;
}
BOOL SkipNextBlock(TImage *pImage)
{
int nLen;
if (!pImage->m_pRawData)
return FALSE;
nLen = GetNextBlockLen(pImage);
if (nLen <= 0 || pImage->m_nCurrOffset+nLen> pImage->m_nDataSize)
return FALSE;
pImage->m_nCurrOffset += nLen;
return TRUE;
}
int GetNextBlockLen(TImage *pImage)
{
int nTmp;
enum GIFBlockTypes nBlock;
TGIFImageDescriptor *pIDescr;
int nLCTSize;
nBlock = GetNextBlock(pImage);
switch(nBlock)
{
case BLOCK_UNKNOWN:
return -1;
break;
case BLOCK_TRAILER:
return 1;
break;
case BLOCK_APPEXT:
nTmp = GetSubBlocksLen(pImage,pImage->m_nCurrOffset+sizeof(TGIFAppExtension));
if (nTmp > 0)
return sizeof(TGIFAppExtension)+nTmp;
break;
case BLOCK_COMMEXT:
nTmp = GetSubBlocksLen(pImage,pImage->m_nCurrOffset+sizeof(TGIFCommentExt));
if (nTmp > 0)
return sizeof(TGIFCommentExt)+nTmp;
break;
case BLOCK_CONTROLEXT:
return sizeof(TGIFControlExt);
break;
case BLOCK_PLAINTEXT:
nTmp = GetSubBlocksLen(pImage,pImage->m_nCurrOffset+sizeof(TGIFPlainTextExt));
if (nTmp > 0)
return sizeof(TGIFPlainTextExt)+nTmp;
break;
case BLOCK_IMAGE:
pIDescr = (TGIFImageDescriptor *) (&(pImage->m_pRawData[pImage->m_nCurrOffset]));
nLCTSize = (int)(GetPackedValueImD(pIDescr,ID_PACKED_LOCALCT)*3*(1 << (GetPackedValueImD(pIDescr,ID_PACKED_LOCALCTSIZE)+1)));
nTmp = GetSubBlocksLen(pImage,pImage->m_nCurrOffset+sizeof(TGIFImageDescriptor) + nLCTSize + 1);
if (nTmp > 0)
return sizeof(TGIFImageDescriptor) + nLCTSize + 1 + nTmp;
break;
};
return 0;
}
BOOL GetNextGraphicBlock(TImage *pImage,
TFrame *pFrame,
UINT *pBlockLen,
UINT *pDelay,
SIZE *pBlockSize,
SIZE *pBlockOffset,
UINT *pDisposal,
int nWidth,
int nHeight)
{
enum GIFBlockTypes nBlock;
int nStart ;
int nBlockLen;
TGIFControlExt *pControl;
TGIFImageDescriptor *pImgDscpt ;
HGLOBAL hGlobal;
int nOffset = 0;
unsigned char *pGlobal;
if (!pImage->m_pRawData)
return NULL;
// GIF header + LSDescriptor [+ GCT] [+ Control block] + Data
*pDisposal = 0;
nBlock = GetNextBlock(pImage);
while ((nBlock != BLOCK_CONTROLEXT) &&(nBlock != BLOCK_IMAGE) &&(nBlock != BLOCK_PLAINTEXT) &&(nBlock != BLOCK_UNKNOWN) &&(nBlock != BLOCK_TRAILER))
{
if (!SkipNextBlock(pImage))
return NULL;
nBlock = GetNextBlock(pImage);
};
if ((nBlock == BLOCK_UNKNOWN) ||(nBlock == BLOCK_TRAILER))
return NULL;
// it's either a controlext, an image or a plain text block
nStart = pImage->m_nCurrOffset;
nBlockLen = GetNextBlockLen(pImage);
if (nBlockLen <= 0)
return NULL;
if (nBlock == BLOCK_CONTROLEXT)
{
// get the following data
pControl = (TGIFControlExt *)(&pImage->m_pRawData[pImage->m_nCurrOffset]);
// store delay time
*pDelay = pControl->m_wDelayTime;
// store disposal method
*pDisposal = GetPackedValueCon(pControl,GCX_PACKED_DISPOSAL);
if (!SkipNextBlock(pImage))
return NULL;
nBlock = GetNextBlock(pImage);
// skip everything until we find data to display
// (image block or plain-text block)
while ((nBlock != BLOCK_IMAGE) &&(nBlock != BLOCK_PLAINTEXT) &&(nBlock != BLOCK_UNKNOWN) &&(nBlock != BLOCK_TRAILER))
{
if (!SkipNextBlock(pImage))
return NULL;
nBlock = GetNextBlock(pImage);
nBlockLen += GetNextBlockLen(pImage);
};
if ((nBlock == BLOCK_UNKNOWN) || (nBlock == BLOCK_TRAILER))
return NULL;
nBlockLen += GetNextBlockLen(pImage);
}
else
*pDelay = -1; // to indicate that there was no delay value
if (nBlock == BLOCK_IMAGE)
{
// store size and offsets
pImgDscpt = (TGIFImageDescriptor *) (&pImage->m_pRawData[pImage->m_nCurrOffset]);
pBlockSize->cx = pImgDscpt->m_wWidth;
pBlockSize->cy = pImgDscpt->m_wHeight;
pBlockOffset->cx = pImgDscpt->m_wLeftPos;
pBlockOffset->cy = pImgDscpt->m_wTopPos;
};
if (!SkipNextBlock(pImage))
return NULL;
if(!FrameDec(pImage,&((pImage->m_pRawData)[nStart]),nStart,nBlockLen,pFrame,nWidth,nHeight))
return FALSE;
return TRUE;
}
BOOL IsGIF(TImage *pImage)
{
return pImage->m_bIsGIF;
}
BOOL IsAnimatedGIF(TImage *pImage)
{
return (pImage->m_bIsGIF && (pImage->m_nFrameCount> 1));
}
BOOL IsPlaying(TImage *pImage)
{
return pImage->m_bIsPlaying;
}
int GetFrameCount(TImage *pImage)
{
if (!IsAnimatedGIF(pImage))
return 0;
return pImage->m_nFrameCount; //to be detailed ,,yajun
}
BOOL FrameDec(TImage *pImage,
U8 *pSData,
int nStart,
int nBlockLen,
TFrame *pFrame,
int nWidth,
int nHeight)
{
int step = 0,WritePos = 0,processImage = 1;
int nBlckSze;
U8 i,Output,cCurByte,cCurCodeSize,Group;
U16 NewCode , MyCode ;
U16 OldCode , FCode ;
U16 EndCode , ClearCode,BitPosition,ByteCountInBlock;
U16 slot , newcodes , TopSlot;
U8 *sp ;
U8 R,G,B;
U8 *stack;
U8 *suffix;
U16 *prefix;
U8 *stmp;
U16 *ptmp;
int stackSize,suffixSize,prefixSize;
int deltaSize = 1024;
int stackCount=0,suffixCount=0,prefixCount=0;
//////////////////////////////////////////////////////////////
int oldWidth,oldHeight,ImgMaxSide,ImgMinSide,ScrMaxSide,ScrMinSide;
if(NU_SUCCESS !=NU_Allocate_Memory(&System_Memory,&stack,4096*sizeof(U8),0))
return FALSE;
else
stackSize = 4096;
if(NU_SUCCESS !=NU_Allocate_Memory(&System_Memory,&suffix,4096*sizeof(U8),0)){
NU_Deallocate_Memory(stack);
return FALSE;
}
else
suffixSize = 4096;
if(NU_SUCCESS !=NU_Allocate_Memory(&System_Memory,&prefix,4096*sizeof(U16),0)){
NU_Deallocate_Memory(stack);
NU_Deallocate_Memory(suffix);
return FALSE;
}
else
prefixSize = 4096;
cCurByte = pSData[step++];
////////////////////////////////////////////////
while(processImage && cCurByte!= 0x3B)
{
switch( cCurByte )
{
case 0x21:
cCurByte = pSData[step++];
switch( cCurByte )
{
case 0xF9:
nBlckSze = pSData[step++];
cCurByte = pSData[step++];
pFrame->m_TransparentFlag= cCurByte & 0x01;
pFrame->m_controlExt.m_wDelayTime = pSData[step++];
pFrame->m_controlExt.m_wDelayTime += ( pSData[step++] << 8);
pFrame->m_controlExt.m_cTColorIndex = pSData[step++];
cCurByte = pSData[step++];
if ( cCurByte == 0 )
break;
case 0x01:
pFrame->m_plainTextExt.m_cBlockSize= pSData[step++] ;
pFrame->m_plainTextExt.m_wLeftPos = ( pSData[step++] << 8);
pFrame->m_plainTextExt.m_wLeftPos += pSData[step++];
pFrame->m_plainTextExt.m_wTopPos = ( pSData[step++] << 8);
pFrame->m_plainTextExt.m_wTopPos += pSData[step++];
pFrame->m_plainTextExt.m_wGridWidth = (pSData[step++] << 8);
pFrame->m_plainTextExt.m_wGridWidth += pSData[step++];
pFrame->m_plainTextExt.m_wGridHeight = ( pSData[step++] << 8);
pFrame->m_plainTextExt.m_wGridHeight += pSData[step++] ;
pFrame->m_plainTextExt.m_cCellWidth = pSData[step++];
pFrame->m_plainTextExt.m_cCellHeight = pSData[step++];
pFrame->m_plainTextExt.m_cFgColor = pSData[step++];
pFrame->m_plainTextExt.m_cBkColor = pSData[step++];
nBlckSze= pSData[step++] ;
while( nBlckSze!= 0 )
{
for ( i = 0 ; i <= nBlckSze-1 ; i ++ )
pFrame->m_PlnTexExt_plainTData[i] = pSData[step++];
nBlckSze= pSData[step++] ;
}
break;
case 0xFE:
nBlckSze = pSData[step++] ;
while( nBlckSze != 0 )
{
for ( i = 0 ; i <= nBlckSze - 1 ; i ++ )
pFrame->m_ComExt_commentData[i] = pSData[step++];
nBlckSze= pSData[step++];
}
break;
case 0xFF:
pFrame->m_appExtension.m_cBlockSize = pSData[step++];
for ( i = 0 ; i <= 7 ; i ++ )
pFrame->m_appExtension.m_cAppIdentifier[i] = pSData[step++];
for ( i = 0 ; i <= 2 ; i ++ )
pFrame->m_appExtension.m_cAppAuth[i] = pSData[step++];
nBlckSze= pSData[step++];
for ( i = 0 ; i <= nBlckSze - 1 ; i ++ )
pFrame->m_AppExt_commentData[i] = pSData[step++];
cCurByte = pSData[step++];
if ( cCurByte == 0 )
break;
default:
break;
}
break;
case 0x2C:
processImage = 0;
pFrame->m_imageDescriptor.m_wLeftPos = pSData[step++];
pFrame->m_imageDescriptor.m_wLeftPos += ( pSData[step++] << 8);
pFrame->m_imageDescriptor.m_wTopPos = pSData[step++];
pFrame->m_imageDescriptor.m_wTopPos += (pSData[step++] << 8);
pFrame->m_imageDescriptor.m_wWidth = pSData[step++];
pFrame->m_imageDescriptor.m_wWidth +=( pSData[step++] << 8);
if(pFrame->m_imageDescriptor.m_wWidth>pImage->m_PictureSize.cx)
pImage->m_PictureSize.cx = pFrame->m_imageDescriptor.m_wWidth;
pFrame->m_imageDescriptor.m_wHeight = pSData[step++];
pFrame->m_imageDescriptor.m_wHeight += ( pSData[step++] << 8);
if(pFrame->m_imageDescriptor.m_wHeight>pImage->m_PictureSize.cy)
pImage->m_PictureSize.cy = pFrame->m_imageDescriptor.m_wHeight;
cCurByte = pSData[step++] ;
pFrame->m_ImaDesExt_sPackFields.m_LCTSize = cCurByte & 0x07;
pFrame->m_ImaDesExt_sPackFields.m_Reserved = ( cCurByte & 0x18 ) >> 3;
pFrame->m_ImaDesExt_sPackFields.m_SortFlag = ( cCurByte & 0x20 ) >> 5;
pFrame->m_ImaDesExt_sPackFields.m_InterlaceFlag = ( cCurByte & 0x40 ) >> 6;
pFrame->m_ImaDesExt_sPackFields.m_LCTFlag = ( cCurByte & 0x80 ) >> 7;
if ( pFrame->m_ImaDesExt_sPackFields.m_LCTFlag )
{
pFrame->m_LCTPos = step + nStart;
step += 3 * ( 2 << pFrame->m_ImaDesExt_sPackFields.m_LCTSize);
}
else
pFrame->m_LCTPos = pImage->m_nGlobalCTPos;
//////////////////////////////////////////////////////
pFrame->m_LZWMinCodeSize = pSData[step++];
cCurCodeSize = pFrame->m_LZWMinCodeSize + 1;
TopSlot = 1 <<cCurCodeSize;
ClearCode = 1 << pFrame->m_LZWMinCodeSize;
EndCode = ClearCode + 1;
slot = newcodes = EndCode +1;
OldCode = FCode = 0;
sp = stack;
Group = 1 ;
BitPosition = 0;
pFrame->m_nBlockSize = pSData[step++];
cCurByte = pSData[step++] ;
ByteCountInBlock = 1;
while (1)
{
if (pFrame->m_nBlockSize == 0 )
break ;
NewCode = GetNewCode(pFrame,pSData,cCurCodeSize,&cCurByte,&step,&BitPosition,&ByteCountInBlock);
if (pFrame->m_nBlockSize == 0 )
break ;
if ( NewCode == ClearCode )
{
cCurCodeSize = pFrame->m_LZWMinCodeSize + 1;
slot = newcodes ;
TopSlot = 1 << cCurCodeSize;
while ((NewCode = GetNewCode(pFrame,pSData,cCurCodeSize,&cCurByte,&step,&BitPosition,&ByteCountInBlock) )== ClearCode)
;
if (NewCode == EndCode)
break;
if (NewCode >= slot)
NewCode = 0;
OldCode = FCode = NewCode;
Output = NewCode ;
if(pFrame->m_ImaDesExt_sPackFields.m_InterlaceFlag)
if(!InterLaceWriteToFrame(pFrame,WritePos++,R,G,B)){
NU_Deallocate_Memory(stack);
NU_Deallocate_Memory(suffix);
NU_Deallocate_Memory(prefix);
return FALSE;
}
else
if(!WriteToFrame(pFrame,WritePos++,R,G,B)){
NU_Deallocate_Memory(stack);
NU_Deallocate_Memory(suffix);
NU_Deallocate_Memory(prefix);
return FALSE;
}
}
else
{
MyCode = NewCode ;
if (MyCode >= slot)
{
MyCode = OldCode ;
*sp++ = FCode;
if(sp==stack+stackSize){
stackSize += deltaSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -