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

📄 recognizer.cpp

📁 linux下的一款播放器
💻 CPP
字号:
#include "ihxpckts.h"#include "hxbuffer.h"#include "hlxclib/ctype.h" /* for isspace() */#include "hxmarsh.h"      /* for getshort() */#include "recognizer.h"#define REALMEDIA_MIME_TYPE             "application/x-pn-realmedia"#define REALAUDIO_MIME_TYPE             "audio/x-pn-realaudio"#define FLASH_MIME_TYPE                 "application/x-shockwave-flash"#define REALAUDIO_METAFILE_MIME_TYPE    "audio/x-pn-realaudio"#define REALAUDIO_PLUGIN_MIME_TYPE      "audio/x-pn-realaudio-plugin"#define SMIL_MIME_TYPE                  "application/smil"// length of buffer read from file and passed to recognizer#if defined(_UNIX) && !defined(_MAC_UNIX)// we want a little more data, since we need to try to detect smil, ram and mp3#define RECOG_LEN 4096#else#define RECOG_LEN 512#endif #if !defined (_SYMBIAN)HX_RESULT CHXFileRecognizer::GetMimeType(const char* pFileName, IHXBuffer* pBuffer, REF(IHXBuffer*) pMimeType){    HX_RESULT res = HXR_FAIL;    const char* pMimeTypeStr = NULL;#if defined(_UNIX) && !defined(_MAC_UNIX)    do    {	res = GetMimeTypeFromMagic(pBuffer, pMimeTypeStr);	if (SUCCEEDED(res))	    break;	res = TestSMILFile(pBuffer, pFileName, pMimeTypeStr);	if (SUCCEEDED(res))	    break;	res = TestRAMFile(pBuffer, pFileName, pMimeTypeStr);	if (SUCCEEDED(res))	    break;	res = TestMP3File(pBuffer, pFileName, pMimeTypeStr);    }    while (0);#else // #if defined(_UNIX) && !defined(_MAC_UNIX)    if (IsSDPFile(pBuffer))    {	pMimeTypeStr = "application/sdp";	res = HXR_OK;    }#endif // #if defined(_UNIX) && !defined(_MAC_UNIX)    if (pMimeTypeStr)    {        // convert mime type to IHXBuffer        pMimeType = new CHXBuffer;        if (pMimeType)        {            pMimeType->AddRef();            int len = strlen(pMimeTypeStr);	    res = pMimeType->Set((const UCHAR*)pMimeTypeStr, len + 1);	    if (FAILED(res))	    {		HX_RELEASE(pMimeType);	    }        }	else	{	    res = HXR_OUTOFMEMORY;	}    }    return res;}#endif#if defined(_UNIX) && !defined(_MAC_UNIX)HX_RESULTCHXFileRecognizer::GetMimeTypeFromMagic(IHXBuffer* pBuffer,					REF(const char*) pMimeType){    HX_RESULT res = HXR_FAIL;    pMimeType = NULL;    HX_ASSERT(pBuffer);    if (pBuffer && pBuffer->GetSize())    {	UCHAR* pData = pBuffer->GetBuffer();	UINT32 uLength = pBuffer->GetSize();	// map magic data to a mime type	typedef struct	{	    UINT32 uOffset;	    const char* pMagic;	    UINT32 uLength;	    const char* pMimeType;	} magic_data;	// these are the magic tricks we know	const magic_data kMagicMap[] =	    {		{ 0, "v=",               2, "application/sdp" },		{ 0, ".RA ",             4, REALAUDIO_MIME_TYPE },		{ 0, ".RMF",             4, REALMEDIA_MIME_TYPE },		{ 0, ".RMS",             4, REALMEDIA_MIME_TYPE },		{ 0, "OggS",             4, "audio/x-ogg", },		{ 0, "#!AMR",            5, "audio/amr" },		{ 0, "WAVE",             4, "audio/x-wav" },		{ 0, "GIF89a",           6, "image/gif" },		{ 0, "GIF87a",           6, "image/gif" },		{ 0, "\211PNG",          4, "image/png" },		{ 0, "\377\330\377\340", 4, "image/jpeg" },		{ 0, "BM",               2, "image/bmp" },		{ 0, "\355\253\356\333", 4, "application/x-rpm" },		{ 0, "FWS",              3, FLASH_MIME_TYPE },		{ 0, "CWS",              3, FLASH_MIME_TYPE },		{ 0, "#EXTM3U",          7, "audio/scpls" },		{ 0, NULL, 0, NULL } // null terminator	    };	// find a matching magic string	for (const magic_data* pCursor = kMagicMap; pCursor->pMagic; ++pCursor)	{	    if (pCursor->uOffset + pCursor->uLength < uLength &&		memcmp(pData + pCursor->uOffset, 		       pCursor->pMagic, pCursor->uLength) == 0)	    {		pMimeType = pCursor->pMimeType;		res = HXR_OK;		break;	    }	}    }    return res;}HX_RESULTCHXFileRecognizer::TestMP3File(IHXBuffer* pBuffer,			       const char* pFileName,			       REF(const char*) pMimeType){    HX_RESULT res = HXR_FAIL;    HX_ASSERT(pBuffer);    BOOL bMPA = FALSE;    BOOL bID3 = FALSE;    if (pBuffer->GetSize() >= 4)    {	const char* pBegin = (const char*)pBuffer->GetBuffer();	// XXXNH: I stole this from /usr/share/misc/magic and it seems to	// do a good job of guessing mp3	UINT16 uShort = getshort((UINT8*)pBegin);	if ((uShort & 0xffe0) == 0xffe0 &&	    (uShort & 0x0018) != 0x0008 &&	    (uShort & 0x0006) != 0x0000)	{	    bMPA = TRUE;	}		else if (memcmp(pBegin, "ID3\003", 4) == 0)	{	    bID3 = TRUE;	}    }    if (bMPA || bID3)    {	res = HXR_OK;	pMimeType = "audio/mp3";    }    return res;}HX_RESULTCHXFileRecognizer::TestSMILFile(IHXBuffer* pBuffer,				const char* pFileName,				REF(const char*) pMimeType){    HX_RESULT res = HXR_FAIL;    HX_ASSERT(pBuffer);    const char* pExt = strrchr(pFileName, '.');    BOOL bValidExt = pExt && (strcasecmp(pExt, ".smi") == 0 ||			      strcasecmp(pExt, ".smil") == 0);    const char* pBegin = (const char*)pBuffer->GetBuffer();    UINT32 uLen = pBuffer->GetSize();    const char* pEnd = (const char*)((UINT32)pBegin + uLen);    BOOL bSMILFound = FALSE;    BOOL bBodyFound = FALSE;    for (const char* pCursor = pBegin; 	 (!bSMILFound || !bBodyFound) && pCursor && pCursor < pEnd; 	 pCursor = strpbrk(pCursor+1, "\n\r")) // next line    {	// eat whitespace	while (isspace(*pCursor) && pCursor < pEnd)	    ++pCursor;	const char* pTag = strchr(pCursor, '<');	while (pTag && (!bSMILFound || !bBodyFound))	{	    if (!bSMILFound && strncasecmp(pTag, "<smil", 5) == 0)	    {		bSMILFound = TRUE;	    }	    else if (!bBodyFound && strncasecmp(pTag, "<body", 5) == 0)	    {		bBodyFound = TRUE;	    }	    pTag = strchr(pTag+1, '<');	}    }    if (bSMILFound && (bBodyFound || bValidExt))    {	// very likely a SMIL file	pMimeType = SMIL_MIME_TYPE;	res = HXR_OK;    }    return res;}HX_RESULTCHXFileRecognizer::TestRAMFile(IHXBuffer* pBuffer,			       const char* pFileName,			       REF(const char*) pMimeType){    HX_RESULT res = HXR_FAIL;    HX_ASSERT(pBuffer);    const char* pBegin = (const char*)pBuffer->GetBuffer();    UINT32 uLen = pBuffer->GetSize();    const char* pEnd = (const char*)((UINT32)pBegin + uLen);    BOOL bProtocolFound = FALSE;    BOOL bHTML = FALSE;    for (const char* pCursor = pBegin; pCursor && pCursor < pEnd; 	 pCursor = strpbrk(pCursor+1, "\n\r")) // next line    {	// eat whitespace	while (isspace(*pCursor) && pCursor < pEnd)	    ++pCursor;	if (pCursor && pCursor < pEnd && *pCursor != '#') // skip comments	{	    // do we have an html tag?	    const char* pTag = strchr(pCursor, '<');	    if (pTag && strncasecmp(pCursor, "<html", 5) == 0)	    {		bHTML = TRUE;		break;	    }	    // find a protocol?	    if (strncasecmp(pCursor, "rtsp://", 7) == 0 ||		strncasecmp(pCursor, "http://", 7) == 0 ||		strncasecmp(pCursor, "file://", 7) == 0 ||		strncasecmp(pCursor, "pnm://", 6) == 0)	    {		bProtocolFound = TRUE;		break;	    }	}    }    if (!bHTML && bProtocolFound)    {	// this is probably a RAM file	const char* pExt = strrchr(pFileName, '.');	if (pExt && strcasecmp(pExt, ".rpm") == 0)	{	    pMimeType = REALAUDIO_PLUGIN_MIME_TYPE;	}	else	{	    pMimeType = REALAUDIO_METAFILE_MIME_TYPE;	}	res = HXR_OK;    }    return res;}#else // #if defined(_UNIX) && !defined(_MAC_UNIX)BOOLCHXFileRecognizer::IsSDPFile(IHXBuffer* pBuffer){    BOOL bResult = FALSE;    if (pBuffer && pBuffer->GetSize())    {        if (0 == strncmp((const char*)pBuffer->GetBuffer(), "v=", 2))        {            bResult = TRUE;        }    }    return bResult;}#endif // #if defined(_UNIX) && !defined(_MAC_UNIX)CHXFileRecognizer::CHXFileRecognizer()    : m_lRefCount(0),      m_pFile(NULL),      m_pResponse(NULL),      m_pBuffer(NULL),      m_bGetMimeTypeDone(FALSE){}CHXFileRecognizer::~CHXFileRecognizer(){    HX_RELEASE(m_pBuffer);    HX_RELEASE(m_pResponse);    HX_RELEASE(m_pFile);}STDMETHODIMP CHXFileRecognizer::QueryInterface(REFIID riid, void** ppvObj){    HX_RESULT ret = HXR_OK;    if (IsEqualIID(riid, IID_IHXFileRecognizer))    {	AddRef();	*ppvObj = (IHXFileRecognizer*)this;    }    else if (IsEqualIID(riid, IID_IHXFileResponse))    {	AddRef();	*ppvObj = (IHXFileResponse*)this;    }    else if (IsEqualIID(riid, IID_IUnknown))    {	AddRef();	*ppvObj = this;    }    else    {	*ppvObj = NULL;	ret = HXR_NOINTERFACE;    }    return ret;}STDMETHODIMP_(ULONG32) CHXFileRecognizer::AddRef(){    return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(ULONG32) CHXFileRecognizer::Release(){    if (InterlockedDecrement(&m_lRefCount) > 0)    {        return m_lRefCount;    }    delete this;    return 0;}STDMETHODIMP CHXFileRecognizer::GetMimeType(IHXFileObject* /*IN*/ pFile, 	    IHXFileRecognizerResponse* /*IN*/ pRecognizerResponse){    HX_RESULT ret = HXR_FAIL;    if (pRecognizerResponse)    {	m_pResponse = pRecognizerResponse;	m_pResponse->AddRef();    }        // get our own IHXFileResponse interface    IHXFileResponse* pFileResponse = NULL;    ret = QueryInterface(IID_IHXFileResponse, (void**) &pFileResponse);    if (SUCCEEDED(ret) && pFileResponse && pFile != NULL)    {	m_pFile = pFile;	m_pFile->AddRef();            ret = m_pFile->Init(HX_FILE_READ | HX_FILE_BINARY, pFileResponse);    }    if (FAILED(ret) && m_pResponse)    {	m_pResponse->GetMimeTypeDone(ret, NULL);    }        HX_RELEASE(pFileResponse);    return ret;}STDMETHODIMP CHXFileRecognizer::InitDone(HX_RESULT status){    if (SUCCEEDED(status))    {	status = m_pFile->Read(RECOG_LEN);    }    if (FAILED(status) && m_pResponse)    {	m_pResponse->GetMimeTypeDone(status, NULL);    }    return status;}STDMETHODIMP CHXFileRecognizer::SeekDone(HX_RESULT /* status */){    if (!m_bGetMimeTypeDone)    {        DoFileRecognize();        HX_RELEASE(m_pBuffer);    }    return HXR_OK;}STDMETHODIMP CHXFileRecognizer::ReadDone(HX_RESULT status,					 IHXBuffer* pBuffer){    if (FAILED(status) && m_pResponse)    {	m_pResponse->GetMimeTypeDone(HXR_FAIL, NULL);    }    else    {        HX_ASSERT(!m_pBuffer);        m_pBuffer = pBuffer;        HX_ADDREF(m_pBuffer);          // seek back to the beginning of the file         // since the same file object will be passed to the file format        if (HXR_OK != m_pFile->Seek(0, FALSE) &&            !m_bGetMimeTypeDone)        {            DoFileRecognize();            HX_RELEASE(m_pBuffer);        }    }    return HXR_OK;}STDMETHODIMP CHXFileRecognizer::WriteDone(HX_RESULT /* status */){    return HXR_OK;}STDMETHODIMP CHXFileRecognizer::CloseDone(HX_RESULT /* status */){    return HXR_OK;}voidCHXFileRecognizer::DoFileRecognize(void){    HX_RESULT   ret = HXR_OK;    IHXBuffer*  pMimeType = NULL;    const char* pFileName = NULL;    m_bGetMimeTypeDone = TRUE;    if (m_pFile)	m_pFile->GetFilename(pFileName);    ret = GetMimeType(pFileName, m_pBuffer, pMimeType);    if (SUCCEEDED(ret) && 	pMimeType && 	pMimeType->GetSize() > 0 && 	m_pResponse)    {	m_pResponse->GetMimeTypeDone(HXR_OK, pMimeType);    }    else    {	m_pResponse->GetMimeTypeDone(HXR_FAIL, NULL);    }    HX_RELEASE(pMimeType);}

⌨️ 快捷键说明

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