📄 gifimage.cpp
字号:
/* 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -