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

📄 gifcodec.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    }                    while (ulBlockSize > 0);                    break;                case kCommentExtension:                case kPlainTextExtension:                    pBuf += 2;                    SkipBlocks(pBuf, pBufLimit);                    break;                case kApplicationExtension:                    ParseApplicationExtension(pBuf);                    break;                default:                    // An extension we don't know - just try to                    // pass it through                    pBuf += 2;                    SkipBlocks(pBuf, pBufLimit);                    break;            }        }        else if (pBuf[0] == kTrailer)        {            /* We found a GIF trailer - we should be at the end of the file */            cMarkList.PushBack((void *) pBuf);	    break;        }        else        {            // Sometimes extra 0 blocks get stuck in GIFs. Check for them            // here - if the current byte is 0, then it's OK. If it's not,            // then we've gotten lost somewhere.            if (pBuf[0] == 0x00)            {                pBuf++;            }            else            {                // Something is wrong with the GIF file.		//		// XXXMEH - instead of returning an error, we will		// be lax and just break here. This will have the effect		// of potentially sending garbage GIFs down to the		// client. The upside is that there are a lot of 		// non-standard GIFs out there that will display in		// browsers and this will allow them to be displayed.		break;            }        }    }    /* The last mark is, of course, the end of the file. */    cMarkList.PushBack((void *) pBufLimit);    /*     * Now we convert our list to a more usable array of ParseSegment's. First     * we compute the number of segments, which is one less than the number     * of marks.     */    m_ulNumSegmentsAllocated = cMarkList.Size() - 1;    if (m_ulNumSegmentsAllocated == 0 || m_ulNumSegmentsAllocated > cMarkList.Size())    {        return HXR_UNEXPECTED;    }    /* Allocate memory for the segment array */    if (m_pSegment)    {        delete [] m_pSegment;        m_pSegment = NULL;    }    m_pSegment = new ParseSegment [m_ulNumSegmentsAllocated];    if (!m_pSegment)    {        return HXR_OUTOFMEMORY;    }    /*     * Now run through the list of marks, computing segments. Note that     * if the mark in the marklist is an extension not necessary for      * deompression, we do not make it into a segment.     */    m_ulNumSegments         = 0;    GListIterator itr       = cMarkList.Begin();    BYTE         *pLastMark = (BYTE *) *itr;    itr++;    do    {        BYTE *pCurMark = (BYTE *) *itr;        /*         * Filter out all unwanted extensions. We don't send application,          * comment, or plain text extensions. We also don't send the GIF         * Trailer         */        if (!((pLastMark[0] == kExtension && (pLastMark[1] == kApplicationExtension ||                                              pLastMark[1] == kCommentExtension     ||                                              pLastMark[1] == kPlainTextExtension)) ||               pLastMark[0] == kTrailer))        {            m_pSegment[m_ulNumSegments].pMark  = pLastMark;            m_pSegment[m_ulNumSegments].ulSize = pCurMark - pLastMark;            m_ulNumSegments++;        }        pLastMark = pCurMark;        itr++;    }    while (itr != cMarkList.End());    /* Now we're done with the list */    cMarkList.EraseAll();    /* Set the state */    m_ulParseState = kStateParseInitialized;    return HXR_OK;}UINT32 CGIFCodec::GetDelayTime(UINT32 i){    if (i >= m_ulNumImages || m_bIsGIF89a == FALSE)    {        return 0;    }    UINT32        ulDelay;    ParseSegment *pSeg = &m_pSegment[1 + (i << 1)];    if (pSeg->pMark[0] == kExtension && pSeg->pMark[1] == kGraphicControlExtension)    {        CGIFImage::GraphicControlExtension cGCE;        CGIFImage::ParseGraphicControlExtension(pSeg->pMark + 3, cGCE);        ulDelay = cGCE.m_ulDelayTime;        if (ulDelay == 0)        {            ulDelay = 1;        }    }    else    {        ulDelay = 0;    }    return ulDelay;}UINT32 CGIFCodec::GetImageDataSize(UINT32 i){    if (i >= m_ulNumImages)    {        return 0;    }    return m_pSegment[2 + (i << 1)].ulSize;}HX_RESULT CGIFCodec::GetPacketBufferLength(UINT32 &rulLen){    /* Check state */    if (m_ulParseState != kStateParseInitialized &&        m_ulParseState != kStateParseInProgress)    {        return HXR_UNEXPECTED;    }    /* Is this our first time here? */    if (m_ulParseState == kStateParseInitialized)    {        /* This is the first time here - we need to find the header length */        UINT32 ulLen = 8                    +  /* Container header size, num images */                       8 * m_ulNumImages    +  /* Image header size and compressed data size */                       m_pSegment[0].ulSize;   /* Container header */        /*         * Add the individual image header sizes - these are the segments which         * begin with either an Image Descriptor or a GCE.         */        UINT32 i;        for (i = 0; i < m_ulNumSegments; i++)        {            BYTE *pMark = m_pSegment[i].pMark;            if ( pMark[0] == kImageDescriptor ||                (pMark[0] == kExtension && pMark[1] == kGraphicControlExtension))            {                ulLen += m_pSegment[i].ulSize;            }        }        /* Set the initial segment for data packet parsing */        m_ulCurSegIndex  = 2;        m_ulCurSegOffset = 0;        /* We have our length */        rulLen = ulLen;    }    else    {        /* This is NOT the first time here - we need to find the data packet length */        BYTE  *pBufStart = m_pSegment[m_ulCurSegIndex].pMark;        BYTE  *pBuf      = pBufStart + m_ulCurSegOffset;        UINT32 ulSize    = 0;        /* If we are at the beginning of a LZW segment, we need to skip the min code size */        if (m_ulCurSegOffset == 0)        {            pBuf++;            ulSize++;        }        /* Advance through the blocks, until we reach the ideal packet size */        UINT32 ulBlockSize;        do        {            ulBlockSize = *pBuf;            ulSize     += ulBlockSize + 1;            pBuf       += ulBlockSize + 1;        }        while (ulBlockSize > 0 && ulSize < kIdealPacketSize);        /*         * Make a check to see if what's left over is not less than the         * minimum packet size. If it IS less than the minimum packet size,         * then go ahead and get the rest of it.         */        UINT32 ulBytesLeftInSegment = pBufStart + m_pSegment[m_ulCurSegIndex].ulSize - pBuf;        if (ulBytesLeftInSegment > 0 && ulBytesLeftInSegment < kMinimumPacketSize)        {            ulSize += ulBytesLeftInSegment;        }        /* Now we have our length */        rulLen = ulSize;    }    return HXR_OK;}UINT32 CGIFCodec::ComputeLZWDataSize(BYTE *pLZW){    /* Skip the minimum code size */    pLZW++;    /* Run through blocks, adding up sizes */    UINT32 ulSum = 0;    UINT32 ulBlockSize;    do    {        ulBlockSize = *pLZW++;        ulSum      += ulBlockSize;        pLZW       += ulBlockSize;    }    while (ulBlockSize > 0);    return ulSum;}HX_RESULT CGIFCodec::GetPacketBuffer(BYTE *pBuffer, UINT32 ulLen, BOOL &rbFirstInImage){    /* Check for input error conditions */    if (pBuffer == NULL || ulLen == 0)    {        return HXR_INVALID_PARAMETER;    }    /* Check state */    if (m_ulParseState != kStateParseInitialized &&        m_ulParseState != kStateParseInProgress)    {        return HXR_UNEXPECTED;    }    /* Is this our first time here? */    if (m_ulParseState == kStateParseInitialized)    {        /* Conainer header size */        Pack32(m_pSegment[0].ulSize, pBuffer);        pBuffer += 4;        /* Number of Images */        Pack32(m_ulNumImages,      pBuffer);        pBuffer += 4;        /* Individual image parameters */        UINT32 i;        for (i = 0; i < m_ulNumImages; i++)        {            /* Individual image header size */            Pack32(m_pSegment[1 + (i << 1)].ulSize, pBuffer);            pBuffer += 4;            /* Individual image compressed data size */            Pack32(ComputeLZWDataSize(m_pSegment[2 + (i << 1)].pMark), pBuffer);            pBuffer += 4;        }        /* Copy container header */        memcpy(pBuffer, m_pSegment[0].pMark, m_pSegment[0].ulSize); /* Flawfinder: ignore */        pBuffer += m_pSegment[0].ulSize;        /* Copy each individual image header */        for (i = 0; i < m_ulNumImages; i++)        {            ParseSegment *pSegment = &m_pSegment[1 + (i << 1)];            memcpy(pBuffer, pSegment->pMark, pSegment->ulSize); /* Flawfinder: ignore */            pBuffer += pSegment->ulSize;        }        /* Clear the flag */        rbFirstInImage = FALSE;        /* Set the new state */        m_ulParseState = kStateParseInProgress;    }    else    {        /* Copy the data packet */        memcpy(pBuffer, /* Flawfinder: ignore */               m_pSegment[m_ulCurSegIndex].pMark + m_ulCurSegOffset,               ulLen);        /* Was this the first packet for one of the images? */        if (m_ulCurSegOffset == 0)        {            rbFirstInImage = TRUE;        }        else        {            rbFirstInImage = FALSE;        }        /* Check to see if we're done with this segment */        if (m_ulCurSegOffset + ulLen >= m_pSegment[m_ulCurSegIndex].ulSize)        {            m_ulCurSegIndex += 2;            m_ulCurSegOffset = 0;        }        else        {            m_ulCurSegOffset += ulLen;        }        /* Check to see if we finished */        if (m_ulCurSegIndex >= m_ulNumSegments)        {            m_ulParseState = kStateParseFinished;        }    }    return HXR_OK;}void CGIFCodec::ParseLogicalScreenDescriptor(BYTE *pBuffer, LogicalScreenDescriptor &cLSD){    /* Read Logical Screen Descriptor */    cLSD.m_ulLogicalScreenWidth     =  (pBuffer[1] << 8) | pBuffer[0];    cLSD.m_ulLogicalScreenHeight    =  (pBuffer[3] << 8) | pBuffer[2];    cLSD.m_bGlobalColorTablePresent =  (pBuffer[4] & 0x80 ? TRUE : FALSE);    cLSD.m_ulOriginalColorBits      = ((pBuffer[4] & 0x70) >> 4) + 1;    cLSD.m_bColorsSorted            =  (pBuffer[4] & 0x08 ? TRUE : FALSE);    cLSD.m_ulColorTableBits         =  (pBuffer[4] & 0x07) + 1;    cLSD.m_ulColorTableNumEntries   = 1 << cLSD.m_ulColorTableBits;    cLSD.m_ulBackgroundColorIndex   =   pBuffer[5];    cLSD.m_ulPixelAspectRatio       =   pBuffer[6];    cLSD.m_fPixelAspectRatio        = (cLSD.m_ulPixelAspectRatio + 15.0F) / 64.0F;}HX_RESULT CGIFCodec::ParseContainerHeader(BYTE * &pBuffer){    /* Verify the signature */    if (pBuffer[0] != 'G' || pBuffer[1] != 'I' || pBuffer[2] != 'F')    {        return HXR_INVALID_OPERATION;    }    pBuffer += 3;    /* Get the version */    if (pBuffer[0] == '8' && pBuffer[1] == '9' && pBuffer[2] == 'a')    {        m_bIsGIF89a = TRUE;    }    else if (pBuffer[0] == '8' && pBuffer[1] == '7' && pBuffer[2] == 'a')    {        m_bIsGIF89a = FALSE;    }    else    {        return HXR_INVALID_OPERATION;    }    pBuffer += 3;    /* Read the Logical Screen Descriptor */    ParseLogicalScreenDescriptor(pBuffer, m_cLSD);    pBuffer += 7;    /* Read the colortable if present */    if (m_cLSD.m_bGlobalColorTablePresent == TRUE)    {        /* Allocate space for the global color table */        if (m_pucGlobalColorMap)        {            delete [] m_pucGlobalColorMap;            m_pucGlobalColorMap = NULL;        }        UINT32 ulColorTableBytes = m_cLSD.m_ulColorTableNumEntries * 3;        m_pucGlobalColorMap = new BYTE [ulColorTableBytes];        if (!m_pucGlobalColorMap)        {            return HXR_OUTOFMEMORY;        }        /* Copy the global color table */        memcpy(m_pucGlobalColorMap, pBuffer, ulColorTableBytes); /* Flawfinder: ignore */        /* Advance the pointer */        pBuffer += ulColorTableBytes;        /* Loop through the images, setting the global color map */        UINT32 i;        for (i = 0; i < m_ulNumImages; i++)        {            m_pImage[i].SetGlobalColorMap(m_cLSD.m_ulColorTableNumEntries,                                          m_pucGlobalColorMap);        }    }    // Reset the delay time sum    m_ulDelayTimeSum = 0;    /* Here we loop through looking for Image Descriptors or Graphic Control Extensions */    HX_RESULT retVal;    UINT32    ulImageNum = 0;    for (;;)    {        UINT32 ulMarker = *pBuffer;        switch(ulMarker)        {            case kImageDescriptor:                retVal = m_pImage[ulImageNum].InitDecompress(pBuffer, m_pImageHeaderSize[ulImageNum]);                if (retVal != HXR_OK)                {                    return retVal;                }                retVal = m_pImage[ulImageNum].SetCompressedBufferSize(m_pCompressedBufferSize[ulImageNum]);                if (retVal != HXR_OK)                {                    return retVal;                }                pBuffer += m_pImageHeaderSize[ulImageNum];                ulImageNum++;                break;            case kExtension:                if (pBuffer[1] == kGraphicControlExtension)                {                    retVal = m_pImage[ulImageNum].InitDecompress(pBuffer, m_pImageHeaderSize[ulImageNum]);                    if (retVal != HXR_OK)

⌨️ 快捷键说明

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