comimgff.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,025 行 · 第 1/3 页

CPP
1,025
字号
        // Set the state
        m_ulState = kStateReady;
        // Report failure to the response interface
        m_pFormatResponse->InitDone(HXR_FAIL);
    }
    else if (m_ulState == kStateGSHCloseDonePending)
    {
        // Clear the return value
        retVal = HXR_OK;
        // Set the state
        m_ulState = kStateReady;
        // Report failure to the response interface
        m_pFormatResponse->StreamHeaderReady(HXR_FAIL, NULL);
    }
    else if (m_ulState == kStateGPCloseDonePending)
    {
        // Clear the return value
        retVal = HXR_OK;
        // Set the state
        m_ulState = kStateReady;
        // Terminate the stream
        m_pFormatResponse->StreamDone(0);
    }

    return retVal;
}

STDMETHODIMP CCommonImageFileFormat::WriteDone(HX_RESULT status)
{
    // We don't ever write, so we don't expect to get this...
    return HXR_UNEXPECTED;
}

STDMETHODIMP CCommonImageFileFormat::MimeTypeFound(HX_RESULT status, const char* pMimeType)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_ulState == kStateIFFMimeTypeFoundPending)
    {
        // If we succeeded, then save the mime type.
        // However, even if we fail, then just go on.
        if (SUCCEEDED(status))
        {
            HX_RELEASE(m_pMimeTypeStr);
            CreateStringBuffer(m_pMimeTypeStr, pMimeType, m_pContext);
        }
        // Clear the return value
        retVal = HXR_OK;
        // Set the state
        m_ulState = kStateReady;
        // Call back to the response interface
        m_pFormatResponse->InitDone(HXR_OK);
    }

    if (FAILED(retVal) && m_pFormatResponse)
    {
        m_pFormatResponse->InitDone(retVal);
    }

    return retVal;
}

HX_RESULT STDAPICALLTYPE CCommonImageFileFormat::HXCreateInstance(IUnknown** ppIUnknown)
{
    HX_RESULT retVal = HXR_FAIL;

    if (ppIUnknown)
    {
        // Set default
        *ppIUnknown = NULL;
        // Create the object
        CCommonImageFileFormat *pObj = new CCommonImageFileFormat();
        if (pObj)
        {
            // QI for IUnknown
            retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
        }
        if (FAILED(retVal))
        {
            HX_DELETE(pObj);
        }
    }

    return retVal;
}


BOOL CCommonImageFileFormat::_GetNextJPGMarker( BYTE** pBuf,
                                                BYTE* pBufEnd,
                                                BYTE* ucMarkerType )
{
    BOOL  bRetVal = FALSE;
    BYTE* pPtr    = *pBuf;
    UINT  unSize  = 0;
    
    // JPEG segment layout:
    // byte  value
    //  1    0xFF(JPEG_MARKER_FLAG)
    //  2    segment type (marker type)
    //  3    MSB segment size. Size does not include bytes 1 & 2.
    //  4    LSB segment size. Size does not include bytes 1 & 2.
    // 5..n  segment data.
    
    //If we are called pointing to the start of a segment, then we get
    //the size and skip to the end of the segment before scanning for
    //the next marker.
    if( pBufEnd-pPtr >= 2 && *pPtr==JPEG_MARKER_FLAG )
    {
        unSize = 0;
        if( _HasSize(*(pPtr+1)) && pBufEnd-pPtr>=4 )
        {
            unSize = (*(pPtr+2)<<8)|*(pPtr+3);
        }
        pPtr += unSize+2; //first 2 segment bytes not included.
        
    }
    
    //Scan for the next JPEG_MARKER_FLAG
    while(pPtr<pBufEnd && JPEG_MARKER_FLAG!=*pPtr)
        pPtr++;

    //Did we find a marker and have at least 4 bytes for the header?
    if( pBufEnd-pPtr>=4 && JPEG_MARKER_FLAG==*pPtr )
    {
        *ucMarkerType = *(pPtr+1);
        *pBuf = pPtr;
        bRetVal = TRUE;
    }

    return bRetVal;
}

BOOL CCommonImageFileFormat::_ParseJPGSOFSegment( BYTE* pBuf,
                                                  BYTE* pBufEnd,
                                                  UINT32& ulWidth,
                                                  UINT32& ulHeight )
{
    // JPEG SOF0, SOF1, SOF2 segments....
    // byte1:  0xFF(JPEG_MARKER_FLAG)
    // byte2:  SOF marker tag
    // byte3:  MSB segment size
    // byte4:  LSB segment size
    //         Size does not include byte1 or byte2
    // byte5:  percision, bits/pixel
    // byte6:  MSB image height
    // byte7:  LSB image height
    // byte8:  MSB image width
    // byte9:  LSB image width
    BOOL bRetVal = FALSE;
    if( pBufEnd-pBuf>=9 )
    {
        ulHeight = (pBuf[5] << 8) | pBuf[6];
        ulWidth  = (pBuf[7] << 8) | pBuf[8];
        bRetVal  = HXR_OK;
    }
    return bRetVal;
}

BOOL CCommonImageFileFormat::_HasSize( BYTE marker )
{
    BOOL bRet = TRUE;
    switch(marker)
    {
       case JPEG_MARKER_RST0: //fall through
       case JPEG_MARKER_RST1: //fall through
       case JPEG_MARKER_RST2: //fall through
       case JPEG_MARKER_RST3: //fall through
       case JPEG_MARKER_RST4: //fall through
       case JPEG_MARKER_RST5: //fall through
       case JPEG_MARKER_RST6: //fall through
       case JPEG_MARKER_RST7: //fall through
       case JPEG_MARKER_TEM:  //fall through
       case JPEG_MARKER_SOI:  //fall through
       case JPEG_MARKER_EOI:
        bRet = FALSE;
        break;
    };
    return bRet;
}

BOOL CCommonImageFileFormat::_IsJPEG( BYTE* pBuf, BYTE* pBufEnd )
{
    BOOL bRetVal = FALSE;
    if( pBufEnd-pBuf >=2 )
    {
        if( JPEG_MARKER_FLAG==pBuf[0] && JPEG_MARKER_SOI==pBuf[1] )
            bRetVal = TRUE;
    }
    return bRetVal;
}


HX_RESULT CCommonImageFileFormat::ParseWidthHeight(IHXBuffer* pBuffer,
                                                   BOOL bIsWBMP,
                                                   REF(UINT32) rulWidth,
                                                   REF(UINT32) rulHeight,
                                                   REF(UINT32) rulImageType)
{
    HX_RESULT retVal = HXR_FAIL;
    
    if (pBuffer)
    {
        // Set the parsing variables
        BYTE* pBuf      = pBuffer->GetBuffer();
        BYTE* pBufLimit = pBuf + pBuffer->GetSize();
        // Do we already know this is WBMP?
        if (bIsWBMP)
        {
            // Parse the WBMP header
            UINT32 ulTmp = 0;
            retVal = ParseWBMPHeader(pBuf,
                                     pBuffer->GetSize(),
                                     rulWidth,
                                     rulHeight,
                                     ulTmp);
            if (SUCCEEDED(retVal))
            {
                // Set the image type
                rulImageType = UNIF_IMAGETYPE_WBMP;
            }
        }
        else
        {
            // This is not WBMP, so check for JPEG, GIF, and PNG
            //
            // Test for JPEG
            BYTE  ucMarkerType = 0;
            BOOL  bExit        = FALSE;
            if( _IsJPEG(pBuf, pBufLimit) )
            {
                // Set the image type
                rulImageType = UNIF_IMAGETYPE_JPEG;
                
                //Start searching for the SOF* 
                while( !bExit && _GetNextJPGMarker(&pBuf, pBufLimit, &ucMarkerType) )
                {
                    switch(ucMarkerType)
                    {
                       case JPEG_MARKER_SOF0: //fall through
                       case JPEG_MARKER_SOF1: //fall through
                       case JPEG_MARKER_SOF2:
                           retVal = _ParseJPGSOFSegment(pBuf, pBufLimit, rulWidth, rulHeight);
                           bExit = TRUE;
                           break;
                       case JPEG_MARKER_EOI:
                           //If we find the end of image marker its too late.
                           retVal = HXR_FAIL;
                           bExit  = TRUE;
                           break;
                       default:
                           break;
                    }
                }
            }
// Uncomment this if we support GIF in the
// future. For now, do GIF with GIF plugins (not unified)
#if 0
            else if (pBuf + 10 <= pBufLimit &&
                     pBuf[0] == 'G' && pBuf[1] == 'I' &&
                     pBuf[2] == 'F' && pBuf[3] == '8' &&
                     (pBuf[4] == '7' || pBuf[4] == '9') &&
                     pBuf[5] == 'a')
            {
                // Set the image type to GIF
                rulImageType = UNIF_IMAGETYPE_GIF;
                // Parse for width and height
                rulWidth  = (pBuf[7] << 8) | pBuf[6];
                rulHeight = (pBuf[9] << 8) | pBuf[8];
                // Clear the return value
                retVal = HXR_OK;
            }
#endif
            else if (pBuf + 8 <= pBufLimit &&
                     pBuf[0] == 0x89 && pBuf[1] == 0x50 &&
                     pBuf[2] == 0x4e && pBuf[3] == 0x47 &&
                     pBuf[4] == 0x0d && pBuf[5] == 0x0a &&
                     pBuf[6] == 0x1a && pBuf[7] == 0x0a)
            {
                // Set the image type to PNG
                rulImageType = UNIF_IMAGETYPE_PNG;
                // Skip the PNG signature
                pBuf += 8;
                // Scan for IHDR chunk, which should be first
                if (pBuf + 16 <= pBufLimit &&
                    pBuf[4] == 'I' && pBuf[5] == 'H' &&
                    pBuf[6] == 'D' && pBuf[7] == 'R')
                {
                    // Get the width and height
                    rulWidth   = (pBuf[8]  << 24) |
                        (pBuf[9]  << 16) |
                        (pBuf[10] <<  8) |
                        (pBuf[11]);
                    rulHeight  = (pBuf[12] << 24) |
                        (pBuf[13] << 16) |
                        (pBuf[14] <<  8) |
                        (pBuf[15]);
                    retVal = HXR_OK;
                }
            }
        }
    }

    return retVal;
}

BOOL CCommonImageFileFormat::IsWBMP(IHXBuffer* pMimeTypeStr, IHXBuffer* pURLStr)
{
    BOOL bRet = FALSE;

    // Check the mime type first (if we have it)
    if (pMimeTypeStr)
    {
        const char* pszMimeType = (const char*) pMimeTypeStr->GetBuffer();
        if (pszMimeType && !strcmp(pszMimeType, "image/x-wap.wbmp"))
        {
            // This *is* a WBMP file
            bRet = TRUE;
        }
    }
    if (!bRet && pURLStr)
    {
        // Do a quick-and-dirty check for the extension
        const char* pszURL = (const char*) pURLStr->GetBuffer();
        if (pszURL)
        {
            char* pszDot = strrchr(pszURL, '.');
            if (pszDot && strlen(pszDot) >= 5)
            {
                char* pszExt = pszDot + 1;
                if (!strncmp(pszExt, "wbmp", 4))
                {
                    bRet = TRUE;
                }
            }
        }
    }

    return bRet;
}

⌨️ 快捷键说明

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