gifimage.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 966 行 · 第 1/3 页
CPP
966 行
/* Set the state */
m_ulState = kStateDecoInitialized;
return HXR_OK;
}
HX_RESULT CGIFImage::Decompress(BYTE *pBuffer, UINT32 ulLen)
{
/* Check for input error conditions */
if (pBuffer == NULL || ulLen == 0)
{
return HXR_INVALID_PARAMETER;
}
/* Check state */
if (m_ulState != kStateDecoInitialized &&
m_ulState != kStateDecoInProgress)
{
return HXR_UNEXPECTED;
}
/* If the state is kStateDecoInitialized, then
* this is the first time in Decompress(). Therefore,
* we need to initialize the LZWCodec.
*/
HX_RESULT retVal;
if (m_ulState == kStateDecoInitialized)
{
/*
* To initialize, we have to extract the first byte of the buffer,
* which is the minimum LZW code size.
*/
INT32 lSize = *pBuffer++;
/* Decrement the length */
ulLen--;
/* Intialize the LZW Codec */
retVal = m_pLZWCodec->InitDecompress(lSize);
if (retVal != HXR_OK)
{
return retVal;
}
/* Intialize the current x and y */
m_ulCurX = 0;
m_ulCurY = 0;
m_ulPass = 0;
m_pOutPtr = m_pOutputBuffer;
/* Set the state so we won't call LZWCodec::InitDecompress() again. */
m_ulState = kStateDecoInProgress;
}
/*
* Now what we have to do is parse our buffer, sending only actual LZW
* data to the GIF codec - NOT the GIF block sizes.
*/
UINT32 ulLZWBlockSize;
do
{
/* Read the block size */
ulLZWBlockSize = *pBuffer++;
/* Decrement the length */
ulLen--;
/* Do we have the amount of data we think we do? */
if (ulLen < ulLZWBlockSize)
{
/* Something's wrong we don't have the amount of data we thought we would */
return HXR_FAILED;
}
/* If we have data, send the LZW compressed data to the LZW codec */
if (ulLZWBlockSize > 0)
{
retVal = m_pLZWCodec->AppendCompressedBuffer(pBuffer, (INT32) ulLZWBlockSize);
if (retVal != HXR_OK)
{
return retVal;
}
/* Update the pointer and decrement the length */
pBuffer += ulLZWBlockSize;
ulLen -= ulLZWBlockSize;
}
}
while (ulLZWBlockSize > 0 && ulLen > 0);
/*
* We've now sent all the data in this buffer, so now decompress until
* we run out of data.
*/
for (;;)
{
/* Get a color index */
INT32 lColorIndex = -1;
retVal = m_pLZWCodec->LZWReadByte(lColorIndex);
if (retVal != HXR_OK)
{
return retVal;
}
/* Did we finish? */
if (m_pLZWCodec->Finished() == TRUE)
{
m_ulState = kStateDecoFinished;
break;
}
// Some GIF encoders don't seem to properly terminate the LZW stream.
// Therefore, we have to check to make sure we're not about
// to write off the end of the image
if (m_ulCurY >= m_cID.m_ulImageHeight || m_ulCurX >= m_cID.m_ulImageWidth)
{
m_ulState = kStateDecoFinished;
break;
}
/* If we suspended AND don't have a valid index, then get out */
if (lColorIndex == -1 && m_pLZWCodec->Suspended() == TRUE)
{
break;
}
/* Place the index in the output buffer */
m_pOutputBuffer[m_ulCurY * m_cID.m_ulImageWidth + m_ulCurX] = (BYTE) lColorIndex;
/* Now update the location of the next pixel value */
BumpPixel();
}
return HXR_OK;
}
HX_RESULT CGIFImage::GetIndexImage(BYTE *pLogicalScreen, UINT32 ulWidth, UINT32 ulHeight,
UINT32 ulPadWidth, BOOL bRowsInverted)
{
if (m_cID.m_ulImageLeft + m_cID.m_ulImageWidth > ulWidth ||
m_cID.m_ulImageTop + m_cID.m_ulImageHeight > ulHeight ||
m_cID.m_bLocalColorTablePresent == TRUE)
{
return HXR_INVALID_PARAMETER;
}
BYTE *pSrc = m_pOutputBuffer;
BYTE *pDst;
INT32 lRowStride;
if (bRowsInverted)
{
pDst = pLogicalScreen + (ulHeight - 1 - m_cID.m_ulImageTop) * ulPadWidth + m_cID.m_ulImageLeft;
lRowStride = - ((INT32) ulPadWidth);
}
else
{
pDst = pLogicalScreen + m_cID.m_ulImageTop * ulPadWidth + m_cID.m_ulImageLeft;
lRowStride = (INT32) ulPadWidth;
}
if (m_bGCEPresent && m_cGCE.m_bTransparentIndexGiven)
{
UINT32 ulX;
UINT32 ulY;
INT32 lDstJump = lRowStride - m_cID.m_ulImageWidth;
for (ulY = m_cID.m_ulImageHeight; ulY; ulY--)
{
for (ulX = m_cID.m_ulImageWidth; ulX; ulX--)
{
if (*pSrc != m_cGCE.m_ulTransparentColorIndex)
{
*pDst = *pSrc;
}
pSrc++;
pDst++;
}
pDst += lDstJump;
}
}
else
{
UINT32 ulRow;
for (ulRow = m_cID.m_ulImageHeight; ulRow; ulRow--)
{
memcpy(pDst, pSrc, m_cID.m_ulImageWidth); /* Flawfinder: ignore */
pSrc += m_cID.m_ulImageWidth;
pDst += lRowStride;
}
}
return HXR_OK;
}
HX_RESULT CGIFImage::GetRGBImage(BYTE *pLogicalScreen, UINT32 ulWidth, UINT32 ulHeight, UINT32 ulPadWidth,
UINT32 ulBytesPerPixel, BOOL bRowsInverted, BOOL bRGBOrdering,
BYTE ucBackRed, BYTE ucBackGreen, BYTE ucBackBlue,
BYTE ucBackAlpha)
{
if (m_cID.m_ulImageLeft + m_cID.m_ulImageWidth > ulWidth ||
m_cID.m_ulImageTop + m_cID.m_ulImageHeight > ulHeight ||
(m_cID.m_bLocalColorTablePresent == FALSE &&
m_bGlobalColorMapPresent == FALSE))
{
return HXR_INVALID_PARAMETER;
}
BYTE *pSrc = m_pOutputBuffer;
BYTE *pDst;
INT32 lRowStride;
if (bRowsInverted)
{
pDst = pLogicalScreen + (ulHeight - 1 - m_cID.m_ulImageTop) * ulPadWidth + m_cID.m_ulImageLeft * ulBytesPerPixel;
lRowStride = - ((INT32) ulPadWidth);
}
else
{
pDst = pLogicalScreen + m_cID.m_ulImageTop * ulPadWidth + m_cID.m_ulImageLeft * ulBytesPerPixel;
lRowStride = ulPadWidth;
}
BYTE *pColorMap = m_pucGlobalColorMap;
if (m_cID.m_bLocalColorTablePresent)
{
pColorMap = m_pucLocalColorMap;
}
UINT32 ulRedIndex;
UINT32 ulGreenIndex;
UINT32 ulBlueIndex;
UINT32 ulAlphaIndex;
if (bRGBOrdering)
{
ulAlphaIndex = 0;
ulRedIndex = 1;
ulGreenIndex = 2;
ulBlueIndex = 3;
}
else
{
ulAlphaIndex = 3;
ulRedIndex = 2;
ulGreenIndex = 1;
ulBlueIndex = 0;
}
if (m_bGCEPresent && m_cGCE.m_bTransparentIndexGiven)
{
// Here we take care of a special case: when the current frame is a subimage and
// the disposal method for this frame is restore to background. Then we have to
// go to all the pixels in the logical screen outside the subimage and also restore
// them to the background color. This fixes PR6182.
if (m_cGCE.m_ulDisposalMethod == kDisposalMethodRestoreToBackground &&
(m_cID.m_ulImageWidth < ulWidth || m_cID.m_ulImageHeight < ulHeight))
{
for (UINT32 ulLogY = 0; ulLogY < ulHeight; ulLogY++)
{
BYTE *pLogRow = pLogicalScreen + ulLogY * ulPadWidth;
for (UINT32 ulLogX = ulWidth; ulLogX; ulLogX--)
{
pLogRow[ulRedIndex] = ucBackRed;
pLogRow[ulGreenIndex] = ucBackGreen;
pLogRow[ulBlueIndex] = ucBackBlue;
pLogRow[ulAlphaIndex] = ucBackAlpha;
pLogRow += ulBytesPerPixel;
}
}
}
UINT32 ulX;
UINT32 ulY;
INT32 lDstJump = lRowStride - ((INT32) (m_cID.m_ulImageWidth * ulBytesPerPixel));
BYTE *pMap;
for (ulY = m_cID.m_ulImageHeight; ulY; ulY--)
{
for (ulX = m_cID.m_ulImageWidth; ulX; ulX--)
{
UINT32 ulColorIndex = *pSrc++;
if (ulColorIndex != m_cGCE.m_ulTransparentColorIndex)
{
pMap = pColorMap + (ulColorIndex * 3);
pDst[ulRedIndex] = pMap[0];
pDst[ulGreenIndex] = pMap[1];
pDst[ulBlueIndex] = pMap[2];
}
else
{
if (m_cGCE.m_ulDisposalMethod == kDisposalMethodRestoreToBackground)
{
pDst[ulRedIndex] = ucBackRed;
pDst[ulGreenIndex] = ucBackGreen;
pDst[ulBlueIndex] = ucBackBlue;
pDst[ulAlphaIndex] = ucBackAlpha;
}
}
pDst += ulBytesPerPixel;
}
pDst += lDstJump;
}
}
else
{
UINT32 ulX;
UINT32 ulY;
INT32 lDstJump = lRowStride - ((INT32) (m_cID.m_ulImageWidth * ulBytesPerPixel));
BYTE *pMap;
for (ulY = m_cID.m_ulImageHeight; ulY; ulY--)
{
for (ulX = m_cID.m_ulImageWidth; ulX; ulX--)
{
UINT32 ulColorIndex = *pSrc++;
pMap = pColorMap + (ulColorIndex * 3);
pDst[ulRedIndex] = pMap[0];
pDst[ulGreenIndex] = pMap[1];
pDst[ulBlueIndex] = pMap[2];
pDst += ulBytesPerPixel;
}
pDst += lDstJump;
}
}
return HXR_OK;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?