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

📄 pxpngdec.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        // We handle transformations on a per-color-type basis        if (ulColorType == PNG_COLOR_TYPE_GRAY)        {            // All bit depths (1, 2, 4, 8, 16) are allowed for PNG_COLOR_TYPE_GRAY, so            // if it's less than 8bpp, we need to expand to 8bpp            if (ulBitDepth < 8 || png_get_valid(png_ptr, info, PNG_INFO_tRNS))            {                png_set_expand(png_ptr);            }            // If it's 16bpp, we need to go down to 8bpp            if (ulBitDepth > 8)            {                png_set_strip_16(png_ptr);            }            // Convert gray to RGB            png_set_gray_to_rgb(png_ptr);            // If we have a tRNS chunk, then we will have expanded it            // to a full alpha channel in png_set_expand(), so we            // have to check so we can deal with alpha            if (png_get_valid(png_ptr, info, PNG_INFO_tRNS))            {                // If we are big-endan we want ARGB, if we are little endian, we need BGRA.                // However, we don't need to worry about RGB vs. BGR since we are converting                // from gray so R = G = B.                if (bBigEndian)                {                    png_set_swap_alpha(png_ptr);                }                // PNG thinks that A = 0 is fully transparent and A = 255 is fully                // opaque. We want the opposite (A = 0 is fully opaque and A = 255 is                // fully transparent). So we call png_set_invert_alpha().                png_set_invert_alpha(png_ptr);            }            else            {                // We DON'T have a tRNS chunk, so we must fill the alpha                // byte with 0, either before or after the RGB triplet.                png_set_filler(png_ptr, 0, (bBigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER));            }        }        else if (ulColorType == PNG_COLOR_TYPE_GRAY_ALPHA)        {            // Only bit depths 8 and 16 are allowed, so we need to just chop 16 down to 8            if (ulBitDepth > 8)            {                png_set_strip_16(png_ptr);            }            // Convert gray to RGB            png_set_gray_to_rgb(png_ptr);            // If we are big-endan we want ARGB, if we are little endian, we need BGRA.            // However, we don't need to worry about RGB vs. BGR since we are converting            // from gray so R = G = B.            if (bBigEndian)            {                png_set_swap_alpha(png_ptr);            }            // PNG thinks that A = 0 is fully transparent and A = 255 is fully            // opaque. We want the opposite (A = 0 is fully opaque and A = 255 is            // fully transparent). So we call png_set_invert_alpha().            png_set_invert_alpha(png_ptr);        }        else if (ulColorType == PNG_COLOR_TYPE_PALETTE)        {            // Convert palettized to RGB            png_set_expand(png_ptr);            // If we are not big endian we need BGR instead of RGB            if (!bBigEndian)            {                png_set_bgr(png_ptr);            }            // If we DID expand a tRNS chunk to a full alpha channel, then            // we need to set how we read alpha. If we did NOT, then we need to            // set the filler value.            if (png_get_valid(png_ptr, info, PNG_INFO_tRNS))            {                // If we are big-endan we want ARGB, if we are little endian, we need BGRA.                if (bBigEndian)                {                    png_set_swap_alpha(png_ptr);                }                // PNG thinks that A = 0 is fully transparent and A = 255 is fully                // opaque. We want the opposite (A = 0 is fully opaque and A = 255 is                // fully transparent). So we call png_set_invert_alpha().                png_set_invert_alpha(png_ptr);            }            else            {                png_set_filler(png_ptr, 0, (bBigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER));            }        }        else if (ulColorType == PNG_COLOR_TYPE_RGB)        {            // Only bit depths 8 and 16 are allowed, so we need to just chop 16 down to 8            if (ulBitDepth > 8)            {                png_set_strip_16(png_ptr);            }            // Set BGR vs. RGB            if (!bBigEndian)            {                png_set_bgr(png_ptr);            }            // If there is a tRNS chunk, we need to expand to full alpha channel            if (png_get_valid(png_ptr, info, PNG_INFO_tRNS))            {                // Expand tRNS chunk to full alpha channel                png_set_expand(png_ptr);                // If we are big-endan we want ARGB, if we are little endian, we need BGRA.                if (bBigEndian)                {                    png_set_swap_alpha(png_ptr);                }                // PNG thinks that A = 0 is fully transparent and A = 255 is fully                // opaque. We want the opposite (A = 0 is fully opaque and A = 255 is                // fully transparent). So we call png_set_invert_alpha().                png_set_invert_alpha(png_ptr);            }            else            {                // There will not be an alpha channel, so we need to set the filler                png_set_filler(png_ptr, 0, (bBigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER));            }        }        else if (ulColorType == PNG_COLOR_TYPE_RGB_ALPHA)        {            // Only bit depths 8 and 16 are allowed, so we need to just chop 16 down to 8            if (ulBitDepth > 8)            {                png_set_strip_16(png_ptr);            }            // Now we know we have 32bpp with alpha, we we just need            // to get the ordering right. Right now, we will get RGBA.            if (bBigEndian)            {                // Get ARGB instead of RGBA                png_set_swap_alpha(png_ptr);            }            else            {                // Get BGRA instead of RGBA                png_set_bgr(png_ptr);            }            // PNG thinks that A = 0 is fully transparent and A = 255 is fully            // opaque. We want the opposite (A = 0 is fully opaque and A = 255 is            // fully transparent). So we call png_set_invert_alpha().            png_set_invert_alpha(png_ptr);        }        // Tell libpng to handle the interlacing details        INT32 lNumPasses = png_set_interlace_handling(png_ptr);        // Update the info struct        png_read_update_info(png_ptr, info);    }}HX_RESULT PXPNGDecode::SetupRowPointers(UINT32 ulHeight, IHXBuffer* pBuffer,                                        UINT32 ulRowStride, BOOL bRowsInverted){    HX_RESULT retVal = HXR_FAIL;    if (ulHeight)    {        HX_VECTOR_DELETE(m_ppImageRow);        m_ppImageRow = new BYTE* [ulHeight];        if (m_ppImageRow)        {            for (UINT32 i = 0; i < ulHeight; i++)            {                UINT32 ulRow    = (bRowsInverted ? ulHeight - 1 - i : i);                m_ppImageRow[i] = pBuffer->GetBuffer() + ulRow * ulRowStride;            }            retVal = HXR_OK;        }    }    return retVal;}void PXPNGDecode::SingleBufferRead(png_structp png_ptr, png_bytep data, png_size_t length){    HX_RESULT retVal = HXR_FAIL;    if (png_ptr && data && length)    {        PXUserIOSingle* pUserIO = (PXUserIOSingle*) png_get_io_ptr(png_ptr);        if (pUserIO && pUserIO->m_pBuffer)        {            UINT32 ulNumBytes = (UINT32) length;            if (pUserIO->m_ulOffset + ulNumBytes > pUserIO->m_pBuffer->GetSize())            {                ulNumBytes = pUserIO->m_pBuffer->GetSize() - pUserIO->m_ulOffset;            }            // Copy the data            memcpy(data, /* Flawfinder: ignore */                   pUserIO->m_pBuffer->GetBuffer() + pUserIO->m_ulOffset,                   ulNumBytes);            // Update the offset            pUserIO->m_ulOffset += ulNumBytes;            // Clear the error return            retVal = HXR_OK;        }    }    if (FAILED(retVal))    {        png_error(png_ptr, "read Error");    }}void PXPNGDecode::HandleError(png_structp png_ptr, png_const_charp message){    // Copy the error string into our custom error struct    CopyErrorString(png_ptr, message);    // longjmp back to the error location    longjmp(png_ptr->jmpbuf, 1);}void PXPNGDecode::HandleWarning(png_structp png_ptr, png_const_charp message){    // Copy the error string into our custom error struct    CopyErrorString(png_ptr, message);}void PXPNGDecode::CopyErrorString(png_structp png_ptr, png_const_charp message){    if (png_ptr && message)    {        PXUserError* pUserError = (PXUserError*) png_get_error_ptr(png_ptr);        if (pUserError)        {            IUnknown* pContext = pUserError->m_pContext;            if (pContext)            {                IHXCommonClassFactory* pFactory = NULL;                HX_RESULT retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,                                                            (void**) &pFactory);                if (SUCCEEDED(retVal))                {                    IHXBuffer* pBuffer = NULL;                    retVal = pFactory->CreateInstance(CLSID_IHXBuffer,                                                      (void**) &pBuffer);                    if (SUCCEEDED(retVal))                    {                        retVal = pBuffer->Set((const BYTE*) message, strlen(message) + 1);                        if (SUCCEEDED(retVal))                        {                            HX_RELEASE(pUserError->m_pErrorStr);                            pUserError->m_pErrorStr = pBuffer;                            pUserError->m_pErrorStr->AddRef();                        }                    }                    HX_RELEASE(pBuffer);                }                HX_RELEASE(pFactory);            }        }    }}void PXPNGDecode::InfoCallback(png_structp png_ptr, png_infop info){    // Set the data state    SetProgressiveDataState(png_ptr, kDataStateInfoCallback);    // Set up the read transforms    SetReadTransforms(png_ptr, info);#ifdef XXXMEH_DEBUG_LOG    DEBUG_OUTF("c:\\pxpnglib.log", (s, "InfoCallback(0x%08X, 0x%08X)\n", png_ptr, info));#endif}void PXPNGDecode::RowCallback(png_structp png_ptr, png_bytep new_row,                              png_uint_32 row_num, int pass){    // Set the data state    SetProgressiveDataState(png_ptr, kDataStateRowCallback);    // We just need to combine the old row with the new row (if    // interlaced) or copy the new row (if not interlaced)    PXUserIOProgressive* pUserIO = (PXUserIOProgressive*) png_get_progressive_ptr(png_ptr);    if (pUserIO && pUserIO->m_ppImageRow && row_num < pUserIO->m_ulNumRows)    {        png_progressive_combine_row(png_ptr, pUserIO->m_ppImageRow[row_num], new_row);    }#ifdef XXXMEH_DEBUG_LOG    DEBUG_OUTF("c:\\pxpnglib.log", (s, "RowCallback(0x%08X, %lu, %lu)\n", new_row, row_num, pass));#endif}void PXPNGDecode::EndCallback(png_structp png_ptr, png_infop info){    // Set the data state    SetProgressiveDataState(png_ptr, kDataStateEndCallback);#ifdef XXXMEH_DEBUG_LOG    DEBUG_OUTF("c:\\pxpnglib.log", (s, "EndCallback(0x%08X, 0x%08X)\n", png_ptr, info));#endif}void PXPNGDecode::SetProgressiveAppState(png_structp png_ptr, UINT32 ulState){    if (png_ptr)    {        PXUserIOProgressive* pUserIO = (PXUserIOProgressive*) png_get_progressive_ptr(png_ptr);        if (pUserIO)        {            pUserIO->m_ulAppState = ulState;        }    }}void PXPNGDecode::SetProgressiveDataState(png_structp png_ptr, UINT32 ulState){    if (png_ptr)    {        PXUserIOProgressive* pUserIO = (PXUserIOProgressive*) png_get_progressive_ptr(png_ptr);        if (pUserIO)        {            pUserIO->m_ulDataState = ulState;        }    }}BOOL PXPNGDecode::IsDataStateEqual(png_structp png_ptr, UINT32 ulState){    BOOL bRet = FALSE;    if (png_ptr)    {        PXUserIOProgressive* pUserIO = (PXUserIOProgressive*) png_get_progressive_ptr(png_ptr);        if (pUserIO && pUserIO->m_ulDataState == ulState)        {            bRet = TRUE;        }    }    return bRet;}

⌨️ 快捷键说明

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