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

📄 pxpngdec.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                                    // Clear the return value                                    retVal = HXR_OK;                                }                            }                            else                            {                                CopyErrorString(m_pPNGStruct, "Not enough data in first packet.");                            }                        }                    }                }            }        }    }    return retVal;}HX_RESULT PXPNGDecode::SetDecompressParam(IHXBuffer* pOutputBuffer,                                          UINT32      ulOutputWidth,                                          UINT32      ulOutputHeight,                                          UINT32      ulRowStride,                                          UINT32      ulBitsPerPixel,                                          UINT32      ulColorFormat,                                          BOOL        bRowsInverted,                                          BOOL        bTransparentIsZero){    HX_LOG_BLOCK( "PXPNGDecode::SetDecompressParam" );    HX_RESULT retVal = HXR_FAIL;    if (pOutputBuffer && ulOutputWidth && ulOutputHeight && ulRowStride &&        ulBitsPerPixel == 32 && ulColorFormat == HX_RGB)    {        if (m_pPNGStruct && m_pPNGInfo)        {            // We either need to be in single-buffer mode (in which            // case we know we've read up through the data) or be in            // progressive-read mode and gotten the InfoCallback.            if (m_bSingleBufferIO ||                (!m_bSingleBufferIO &&                 IsDataStateEqual(m_pPNGStruct, kDataStateInfoCallback)))            {                // Set the error return jump                if (setjmp(m_pPNGStruct->jmpbuf))                {                    // If we get here, then libpng threw an error and                    // we longjmp'd back here.                    return HXR_FAIL;                }                // Check for full size decode                if (ulOutputWidth  == (UINT32) png_get_image_width(m_pPNGStruct, m_pPNGInfo) &&                    ulOutputHeight == (UINT32) png_get_image_height(m_pPNGStruct, m_pPNGInfo))                {                    if (m_bSingleBufferIO)                    {                        // Set up the transforms                        SetReadTransforms(m_pPNGStruct, m_pPNGInfo);                    }                    // libpng by default assumes that 0 is fully transparent and 255 is                    // fully opaque. PXPNGDecode by default outputs alpha in the opposite                    // sense (0 == fully opaque and 255 == fully transparent). The following                    // allows the application using PXPNGDecode to switch back to libpng's                    // default behavior.                    if (bTransparentIsZero)                    {                        png_clear_invert_alpha(m_pPNGStruct);                    }                    // Save a copy of the output buffer                    HX_RELEASE(m_pOutputBuffer);                    m_pOutputBuffer = pOutputBuffer;                    m_pOutputBuffer->AddRef();                    // Set up the row pointers                    retVal = SetupRowPointers(ulOutputHeight,                                              pOutputBuffer,                                              ulRowStride,                                              bRowsInverted);                    if (SUCCEEDED(retVal) && !m_bSingleBufferIO)                    {                        // We just need to copy the number of rows and the                        // m_ppImageRow pointer into progressive user i/o struct                        PXUserIOProgressive* pUserIO = (PXUserIOProgressive*) png_get_progressive_ptr(m_pPNGStruct);                        if (pUserIO)                        {                            pUserIO->m_ulNumRows  = ulOutputHeight;                            HX_VECTOR_DELETE(pUserIO->m_ppImageRow);                            pUserIO->m_ppImageRow = m_ppImageRow;                        }                    }                }            }        }    }    return retVal;}HX_RESULT PXPNGDecode::Decompress(IHXBuffer* pBuffer){    HX_LOG_BLOCK( "PXPNGDecode::Decompress" );        HX_RESULT retVal = HXR_OK;    if (m_pPNGStruct && m_ppImageRow && m_pPNGEndInfo && !m_bFinished)    {        // Set the error return jump        if (setjmp(m_pPNGStruct->jmpbuf))        {            // If we get here, then libpng threw an error and            // we longjmp'd back here.            return HXR_FAIL;        }        // Are we in single-buffer or progressive-read mode?        if (m_bSingleBufferIO)        {            // We are in single-buffer mode. Therefore, we            // can now decompress the whole image. Note that            // in this mode it doesn't matter whether they            // duplicate the first buffer or not.            png_read_image(m_pPNGStruct, m_ppImageRow);            // Now read the end info (might have text or time info)            png_read_end(m_pPNGStruct, m_pPNGEndInfo);            // Set the finished flag            m_bFinished = TRUE;        }        else        {            // If we had deferred processing of part of the            // first buffer, then we need to do that now.            if (m_bDeferFirstBuffer)            {                // Clear the flag                m_bDeferFirstBuffer = FALSE;#ifdef XXXMEH_DEBUG_LOG                DEBUG_OUTF("c:\\pxpnglib.log", (s, "Decompress(): deferred first buffer call to png_process_data()\n"));#endif                // Process the rest of the first buffer                png_process_data(m_pPNGStruct,                                 m_pPNGInfo,                                 (png_bytep)  m_pFirstBuffer->GetBuffer() +                                              m_ulFirstBufferOffset,                                 (png_size_t) m_pFirstBuffer->GetSize() -                                              m_ulFirstBufferOffset);                // Release the first buffer                HX_RELEASE(m_pFirstBuffer);                m_ulFirstBufferOffset = 0;            }            // Make sure if the first buffer is duplicated,            // that we are not passing it in twice.            if (!(m_bFirstDecompress && m_bDupFirstBuffer))            {#ifdef XXXMEH_DEBUG_LOG                DEBUG_OUTF("c:\\pxpnglib.log", (s, "Decompress(): normal call to png_process_data()\n"));#endif                png_process_data(m_pPNGStruct,                                 m_pPNGInfo,                                 (png_bytep)  pBuffer->GetBuffer(),                                 (png_size_t) pBuffer->GetSize());            }            // Check to see if the EndCallback has been             // called. If so, then we are finished.            if (IsDataStateEqual(m_pPNGStruct, kDataStateEndCallback))            {                m_bFinished = TRUE;            }        }        // Clear the first decompress flag        m_bFirstDecompress = FALSE;    }    else    {        retVal = HXR_UNEXPECTED;    }    return retVal;}HX_RESULT PXPNGDecode::GetErrorString(REF(IHXBuffer*) rpErrStr){    HX_RESULT retVal = HXR_FAIL;    if (m_pPNGStruct)    {        PXUserError* pUserError = (PXUserError*) png_get_error_ptr(m_pPNGStruct);        if (pUserError && pUserError->m_pErrorStr)        {            HX_RELEASE(rpErrStr);            rpErrStr = pUserError->m_pErrorStr;            rpErrStr->AddRef();        }    }    return retVal;}void PXPNGDecode::DeallocateErrorHandling(png_structp png_ptr){    if (png_ptr)    {        PXUserError* pUserError = (PXUserError*) png_get_error_ptr(png_ptr);        if (pUserError)        {            HX_RELEASE(pUserError->m_pContext);            HX_RELEASE(pUserError->m_pErrorStr);        }        HX_DELETE(pUserError);    }}void PXPNGDecode::DeallocateIOHandling(png_structp png_ptr){    if (png_ptr)    {        if (m_bSingleBufferIO)        {            // Deallocate any single-buffer IO             PXUserIOSingle* pUserIOSingle = (PXUserIOSingle*) png_get_io_ptr(png_ptr);            if (pUserIOSingle)            {                HX_RELEASE(pUserIOSingle->m_pBuffer);            }            HX_DELETE(pUserIOSingle);        }        else        {            // Deallocate any progressive-read IO            PXUserIOProgressive* pUserIOProg = (PXUserIOProgressive*) png_get_progressive_ptr(png_ptr);            HX_DELETE(pUserIOProg);        }    }}BOOL PXPNGDecode::IsChunkPresent(IHXBuffer* pBuffer, UINT32 ulChunkType,                                 REF(UINT32) rulOffset, REF(UINT32) rulNumBytes,                                 REF(BOOL) rbComplete){    BOOL bRet = FALSE;    if (pBuffer)    {        BYTE* pBufStart = pBuffer->GetBuffer();        BYTE* pBufLimit = pBuffer->GetBuffer() + pBuffer->GetSize();        BYTE* pBuf      = pBufStart;        if (pBuf)        {            UINT32 ulSig0 = (pBuf[0] << 24) |                            (pBuf[1] << 16) |                            (pBuf[2] <<  8) |                            (pBuf[3]);            UINT32 ulSig1 = (pBuf[4] << 24) |                            (pBuf[5] << 16) |                            (pBuf[6] <<  8) |                            (pBuf[7]);            if (ulSig0 == kSig0 && ulSig1 == kSig1)            {                // We detected a signature, so we will skip it                pBuf += 8;            }            // Scan the chunks            while (pBuf < pBufLimit)            {                if (pBuf + 8 <= pBufLimit)                {                    UINT32 ulLength = (pBuf[0] << 24) |                                      (pBuf[1] << 16) |                                      (pBuf[2] <<  8) |                                      (pBuf[3]);                    UINT32 ulType   = (pBuf[4] << 24) |                                      (pBuf[5] << 16) |                                      (pBuf[6] <<  8) |                                      (pBuf[7]);                    UINT32 ulTotal  = 8 + ulLength + 4;                    if (ulType == ulChunkType)                    {                        bRet      = TRUE;                        rulOffset = pBuf - pBufStart;                        if (pBuf + ulTotal <= pBufLimit)                        {                            rbComplete  = TRUE;                            rulNumBytes = ulTotal;                        }                        else                        {                            rbComplete  = FALSE;                            rulNumBytes = pBufLimit - pBuf;                        }			break;                    }                    pBuf += ulTotal;                }                else                {                    pBuf += 8;                }            }        }    }    return bRet;}BOOL PXPNGDecode::IsCompleteChunkPresent(IHXBuffer* pBuffer, UINT32 ulChunkType){    UINT32 ulOffset   = 0;    UINT32 ulNumBytes = 0;    BOOL   bComplete  = FALSE;    BOOL   bPresent   = IsChunkPresent(pBuffer, ulChunkType, ulOffset,                                       ulNumBytes, bComplete);    return (bPresent && bComplete ? TRUE : FALSE);}BOOL PXPNGDecode::GetIHDRInfo(IHXBuffer* pBuffer, REF(UINT32) rulWidth, REF(UINT32) rulHeight){    UINT32 ulOffset   = 0;    UINT32 ulNumBytes = 0;    BOOL   bComplete  = FALSE;    BOOL   bPresent   = IsChunkPresent(pBuffer, kIHDR, ulOffset, ulNumBytes, bComplete);    if (bPresent && bComplete)    {        BYTE* pBuf = pBuffer->GetBuffer() + ulOffset + 8;        rulWidth   = (pBuf[0] << 24) |                     (pBuf[1] << 16) |                     (pBuf[2] <<  8) |                     (pBuf[3]);        rulHeight  = (pBuf[4] << 24) |                     (pBuf[5] << 16) |                     (pBuf[6] <<  8) |                     (pBuf[7]);    }    return (bPresent && bComplete ? TRUE : FALSE);}void PXPNGDecode::SetReadTransforms(png_structp png_ptr, png_infop info){    if (png_ptr && info)    {        UINT32 ulColorType = (UINT32) png_get_color_type(png_ptr, info);        UINT32 ulBitDepth  = (UINT32) png_get_bit_depth(png_ptr, info);        BOOL   bBigEndian  = TestBigEndian();

⌨️ 快捷键说明

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