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

📄 gifcodec.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    {                        return retVal;                    }                    // Add the delay time to the delay time sum                    m_ulDelayTimeSum += m_pImage[ulImageNum].GetDelayTime() * 10;                    retVal = m_pImage[ulImageNum].SetCompressedBufferSize(m_pCompressedBufferSize[ulImageNum]);                    if (retVal != HXR_OK)                    {                        return retVal;                    }                    pBuffer += m_pImageHeaderSize[ulImageNum];                    ulImageNum++;                }                else if (pBuffer[1] == kApplicationExtension)                {                    ParseApplicationExtension(pBuffer);                }                else                {                    /* Skip the extension marker and type */                    pBuffer += 2;                    /* Now skip the extension itself */                    SkipBlocks(pBuffer);                }                break;            case kTrailer:            default:                /* Something went wrong */                return HXR_INVALID_OPERATION;                break;        }        /* If we've gotten all intialized all images, then we're done */        if (ulImageNum >= m_ulNumImages)        {            break;        }    }    return HXR_OK;}void CGIFCodec::SkipBlocks(BYTE * &pBuffer, BYTE* pBufLimit){    // If pBufLimit is NULL, then we won't use it at all.    // If pBufLimit is not NULL, then we will make sure    // we don't go past the end of the buffer    UINT32 ulBlockSize;    do    {        /* Get the block size */        ulBlockSize = *pBuffer++;        /* Skip that amount of bytes */        pBuffer += ulBlockSize;    }    while (ulBlockSize > 0 &&           (!pBufLimit || (pBufLimit && pBuffer < pBufLimit)));}HX_RESULT CGIFCodec::InitDecompress(BYTE *pBuffer, UINT32 ulLen){    /* Check for input error conditions */    if (pBuffer == NULL || ulLen == 0)    {        return HXR_INVALID_PARAMETER;    }    /* Check the state */    if (m_ulState != kStateConstructed)    {        return HXR_UNEXPECTED;    }    /* Get the master header length */    UINT32 ulHeaderLength = UnPack32(pBuffer);    pBuffer += 4;    /* Get the number of images */    m_ulNumImages = UnPack32(pBuffer);    pBuffer += 4;    if (m_ulNumImages == 0)    {        return HXR_UNEXPECTED;    }    /* Allocate array of images */    if (m_pImage)    {        delete [] m_pImage;        m_pImage = NULL;    }    m_pImage = new CGIFImage [m_ulNumImages];    if (!m_pImage)    {        return HXR_OUTOFMEMORY;    }    /* Allocate array for image header sizes */    if (m_pImageHeaderSize)    {        delete [] m_pImageHeaderSize;        m_pImageHeaderSize = NULL;    }    m_pImageHeaderSize = new UINT32 [m_ulNumImages];    if (!m_pImageHeaderSize)    {        if (m_pImage)        {            delete [] m_pImage;            m_pImage = NULL;        }        return HXR_OUTOFMEMORY;    }    /* Allocate array for image header sizes */    if (m_pCompressedBufferSize)    {        delete [] m_pCompressedBufferSize;        m_pCompressedBufferSize = NULL;    }    m_pCompressedBufferSize = new UINT32 [m_ulNumImages];    if (!m_pCompressedBufferSize)    {        if (m_pImage)        {            delete [] m_pImage;            m_pImage = NULL;        }        if (m_pImageHeaderSize)        {            delete [] m_pImageHeaderSize;            m_pImageHeaderSize = NULL;        }        return HXR_OUTOFMEMORY;    }    /* Now set the compressed buffer size for each image */    HX_RESULT retVal;    UINT32    i;    for (i = 0; i < m_ulNumImages; i++)    {        /* Get the image header size */        m_pImageHeaderSize[i] = UnPack32(pBuffer);        pBuffer += 4;        /* Get a compressed buffer size */        m_pCompressedBufferSize[i] = UnPack32(pBuffer);        pBuffer += 4;    }    /* Now parse the container header */    retVal = ParseContainerHeader(pBuffer);    if (retVal != HXR_OK)    {        if (m_pImage)        {            delete [] m_pImage;            m_pImage = NULL;        }        if (m_pImageHeaderSize)        {            delete [] m_pImageHeaderSize;            m_pImageHeaderSize = NULL;        }        return retVal;    }    /* Set the current image */    m_ulCurrentImageIndex = 0;    /* Set the new state */    m_ulState = kStateDecoInitialized;    return HXR_OK;}HX_RESULT CGIFCodec::Decompress(BYTE *pBuffer, UINT32 ulLen, BOOL bNewImage){    /* Check for input error conditions */    if (pBuffer == NULL || ulLen == 0)    {        return HXR_INVALID_PARAMETER;    }    /* Check the state */    if (m_ulState != kStateDecoInitialized && m_ulState != kStateDecoInProgress)    {        return HXR_UNEXPECTED;    }    /* Check to see if the we lost a packet on this image */    if (m_pImage[m_ulCurrentImageIndex].GetValid() == FALSE)    {        /* This image was declared invalid due to a lost packet */        if (bNewImage == FALSE)        {            // We're still on the same image, so we can't do anything            return HXR_OK;        }        // We've moved on to a new image, so we can begin decompressing again        m_ulCurrentImageIndex++;    }    /* All we have to do is pass this data on to the current image */    HX_RESULT retVal = m_pImage[m_ulCurrentImageIndex].Decompress(pBuffer, ulLen);    if (retVal != HXR_OK)    {        return retVal;    }    /* Set the state */    m_ulState = kStateDecoInProgress;    /* Are we finished with this image? */    if (m_pImage[m_ulCurrentImageIndex].Finished() == TRUE)    {        /* Move on to the next image */        m_ulCurrentImageIndex++;        /* If we've done all images, then we're done */        if (m_ulCurrentImageIndex >= m_ulNumImages)        {            m_ulState = kStateDecoFinished;        }    }    return HXR_OK;}INT32 CGIFCodec::ComputeStartingImageIndex(INT32 lCurIndex, INT32 lDesiredIndex){    // Does the buffer currently hold any image now?    INT32 lStartIndex;    INT32 lBaseIndex;    if (lCurIndex == -1 || lCurIndex > lDesiredIndex)    {        // The buffer doesn't have anything in it now, so we must build        // from the last full screen image before or equal to ulImgIndex        // all the way back to 0.        lBaseIndex = 0;    }    else    {        // The buffer currently has a valid image in it, so we only need        // to go back to the first full screen image greater than lCurIndex.        lBaseIndex = lCurIndex + 1;    }    // Find the index of the first image we need to do    for (lStartIndex = lDesiredIndex; lStartIndex >= lBaseIndex; lStartIndex--)    {        if (m_pImage[lStartIndex].GetImageWidth()  == m_cLSD.m_ulLogicalScreenWidth &&            m_pImage[lStartIndex].GetImageHeight() == m_cLSD.m_ulLogicalScreenHeight)        {            break;        }    }    if (lStartIndex < lBaseIndex)    {        lStartIndex = 0;    }    return lStartIndex;}HX_RESULT CGIFCodec::GetIndexImage(INT32 lCurIndex, UINT32 ulImgIndex, BYTE *pBuffer, UINT32 ulWidth, UINT32 ulHeight,                                   UINT32 ulPadWidth, BOOL bRowsInverted){    // Check for input error    if (lCurIndex < -1 || lCurIndex >= (INT32) m_ulNumImages || ulImgIndex >= m_ulNumImages ||        pBuffer == NULL || ulWidth == 0 || ulHeight == 0 || ulPadWidth == 0)    {        return HXR_INVALID_PARAMETER;    }    // Since frames of a GIF can be dependent upon prior frames, we need to    // determine which frame we need to go back to    INT32 lStartIndex = ComputeStartingImageIndex(lCurIndex, (INT32) ulImgIndex);    // Now do the images from lStartIndex to ulImgIndex    INT32 i;    for (i = lStartIndex; i <= (INT32) ulImgIndex; i++)    {        HX_RESULT retVal = m_pImage[i].GetIndexImage(pBuffer, ulWidth, ulHeight,                                                     ulPadWidth, bRowsInverted);        if (retVal != HXR_OK)        {            return retVal;        }    }    return HXR_OK;}HX_RESULT CGIFCodec::GetRGBImage(INT32 lCurIndex, UINT32 ulImgIndex, BYTE *pBuffer, UINT32 ulWidth, UINT32 ulHeight, UINT32 ulPadWidth,                                 UINT32 ulBytesPerPixel, BOOL bRowsInverted, BOOL bRGBOrdering, BYTE ucBackRed, BYTE ucBackGreen, BYTE ucBackBlue,                                 BYTE ucBackAlpha){    // Check for input error    if (lCurIndex < -1 || lCurIndex >= (INT32) m_ulNumImages || ulImgIndex >= m_ulNumImages ||        pBuffer == NULL || ulWidth == 0 || ulHeight == 0 || ulPadWidth == 0 || ulBytesPerPixel == 0)    {        return HXR_INVALID_PARAMETER;    }    // Since frames of a GIF can be dependent upon prior frames, we need to    // determine which frame we need to go back to    INT32 lStartIndex = ComputeStartingImageIndex(lCurIndex, (INT32) ulImgIndex);    // Now do the images from lStartIndex to ulImgIndex    INT32 i;    for (i = lStartIndex; i <= (INT32) ulImgIndex; i++)    {        HX_RESULT retVal = m_pImage[i].GetRGBImage(pBuffer, ulWidth, ulHeight, ulPadWidth,                                                   ulBytesPerPixel, bRowsInverted, bRGBOrdering,                                                   ucBackRed, ucBackGreen, ucBackBlue, ucBackAlpha);        if (retVal != HXR_OK)        {            return retVal;        }    }    return HXR_OK;}HX_RESULT CGIFCodec::GetRGBImageEx(INT32 lCurIndex, UINT32 ulImgIndex, BYTE *pBuffer, UINT32 ulWidth, UINT32 ulHeight,                                   UINT32 ulPadWidth, UINT32 ulBytesPerPixel, BOOL bRowsInverted, BOOL bRGBOrdering,                                   UINT32 ulBgColor, BOOL bMediaOpacity, UINT32 ulMediaOpacity,                                   BOOL bChromaKey, UINT32 ulChromaKey, UINT32 ulChromaKeyTol, UINT32 ulChromaKeyOpacity){    HX_RESULT retVal = HXR_OK;    if (lCurIndex >= -1 && lCurIndex < (INT32) m_ulNumImages &&        ulImgIndex < m_ulNumImages && pBuffer && ulWidth && ulHeight &&        ulPadWidth && ulBytesPerPixel)    {        // Since frames of a GIF can be dependent upon prior frames, we need to        // determine which frame we need to go back to        INT32 lStartIndex = ComputeStartingImageIndex(lCurIndex, (INT32) ulImgIndex);        // Now do the images from lStartIndex to ulImgIndex        INT32 i = 0;        for (i = lStartIndex; i <= (INT32) ulImgIndex; i++)        {            retVal = m_pImage[i].GetRGBImageEx(pBuffer, ulWidth, ulHeight, ulPadWidth,                                               ulBytesPerPixel, bRowsInverted, bRGBOrdering,                                               ulBgColor, bMediaOpacity, ulMediaOpacity,                                               bChromaKey, ulChromaKey, ulChromaKeyTol, ulChromaKeyOpacity);            if (FAILED(retVal))            {                break;            }        }    }    else    {        retVal = HXR_INVALID_PARAMETER;    }    return retVal;}HX_RESULT CGIFCodec::GetRGB32(UINT32 ulImageNum, BYTE *pBuffer, UINT32 ulRowStride, BOOL bRowsInverted){    HX_RESULT retVal = HXR_OK;    if (pBuffer)    {        if (ulImageNum < m_ulNumImages && m_pImage)        {            retVal = m_pImage[ulImageNum].GetRGB32(pBuffer, ulRowStride, bRowsInverted);        }        else        {            retVal = HXR_UNEXPECTED;        }    }    else    {        retVal = HXR_INVALID_PARAMETER;    }    return retVal;}void CGIFCodec::PacketLost(){    // Clear the valid flag for the current image    m_pImage[m_ulCurrentImageIndex].SetValid(FALSE);    // Set the finished flag for this image    m_pImage[m_ulCurrentImageIndex].SetFinished();}BOOL CGIFCodec::LocalColorMapsPresent(){    UINT32 i;    for (i = 0; i < m_ulNumImages; i++)    {        if (m_pImage[i].LocalColorMapPresent())        {            return TRUE;        }    }    return FALSE;}void CGIFCodec::ParseApplicationExtension(BYTE * &pBuf){    pBuf += 2; // skip the extension introducer and the application extension label    // The next block should always be 11 bytes - 8 bytes for application identifier    // and 3 bytes for the application authentication code. If it's not then just    // skip these blocks    if (pBuf[0] == 11)    {        // Now we check to see if this is a NETSCAPE2.0 application extension.        // If it is, then it contains the loop count for the animation.        if (!strncmp((const char *) pBuf + 1, "NETSCAPE2.0", 11))        {            // Yep, we've got a NETSCAPE2.0 application extension,            // so attempt to extract the loop count            if (pBuf[12] == 0x03 && pBuf[13] == 0x01 && pBuf[16] == 0x00)            {                UINT32 ulCount = (pBuf[15] << 8) | pBuf[14];                if (ulCount == 0)                {                    m_ulLoopCount = 0;                }                else                {                    m_ulLoopCount = ulCount + 1;                }                pBuf += 17;            }            else            {                SkipBlocks(pBuf);            }        }        else        {            SkipBlocks(pBuf);        }    }    else    {        SkipBlocks(pBuf);    }}

⌨️ 快捷键说明

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