📄 librarybuilderinternals.cpp
字号:
{
strValue.ReleaseBuffer( 0 );
return FALSE;
}
}
strValue.TrimLeft();
strValue.TrimRight();
if ( strValue.GetLength() == 0 || _tcslen( strValue ) == 0 ) return FALSE;
pXML->AddAttribute( pszAttribute, strValue );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals MP3 scan (threaded)
BOOL CLibraryBuilderInternals::ReadMP3Frames( HANDLE hFile)
{
SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
CXMLElement* pXML = new CXMLElement( NULL, _T("audio") );
if ( ScanMP3Frame( pXML, hFile, 0 ) )
{
return SubmitMetadata( CSchema::uriAudio, pXML );
}
else
{
delete pXML;
return FALSE;
}
}
BOOL CLibraryBuilderInternals::ScanMP3Frame(CXMLElement* pXML, HANDLE hFile, DWORD nIgnore)
{
static DWORD nBitrateTable[16][5] =
{
{ 0, 0, 0, 0 }, { 32, 32, 32, 32, 8 }, { 64, 48, 40, 48, 16 },
{ 96, 56, 48, 56, 24 }, { 128, 64, 56, 64, 32 }, { 160, 80, 64, 80, 40 },
{ 192, 96, 80, 96, 48 }, { 224, 112, 96, 112, 56 }, { 256, 128, 112, 128, 64 },
{ 288, 160, 128, 144, 80 }, { 320, 192, 160, 160, 96 }, { 352, 224, 192, 176, 112 },
{ 384, 256, 224, 192, 128 }, { 416, 320, 256, 224, 144 },{ 448, 384, 320, 256, 160 },
{ 0, 0, 0, 0 }
};
static DWORD nFrequencyTable[4][4] =
{
{ 11025, 0, 22050, 44100 },
{ 12000, 0, 24000, 48000 },
{ 8000, 0, 16000, 32000 },
{ 0, 0, 0, 0 }
};
BYTE nLayer = 0;
BOOL bVariable = FALSE;
__int64 nTotalBitrate = 0;
DWORD nBaseBitrate = 0;
DWORD nBaseFrequency = 0;
DWORD nFrameCount = 0;
DWORD nFrameSize = 0;
DWORD nHeader = 0;
DWORD nRead;
ReadFile( hFile, &nHeader, 4, &nRead, NULL );
if ( nRead != 4 ) return FALSE;
nHeader = SWAP_LONG( nHeader );
for ( DWORD nSeek = 0 ; bVariable || ( nFrameCount < 16 && nSeek < 4096 ) ; nSeek++ )
{
DWORD nTime = GetTickCount();
if ( ( nHeader & 0xFFE00000 ) == 0xFFE00000 )
{
BYTE nVersion = (BYTE)( ( nHeader & 0x00180000 ) >> 19 );
nLayer = (BYTE)( ( nHeader & 0x00060000 ) >> 17 );
BYTE nBitIndex = (BYTE)( ( nHeader & 0x0000F000 ) >> 12 );
BYTE nFreqIndex = (BYTE)( ( nHeader & 0x00000C00 ) >> 10 );
BYTE nChannels = (BYTE)( ( nHeader & 0x000000C0 ) >> 6 );
BOOL bPadding = (BOOL)( nHeader & 0x0200 ) ? TRUE : FALSE;
int nBitColumn = 0;
if ( nVersion == 3 )
{
if ( nLayer == 3 ) nBitColumn = 0;
else if ( nLayer == 2 ) nBitColumn = 1;
else if ( nLayer == 1 ) nBitColumn = 2;
}
else
{
if ( nLayer == 3 ) nBitColumn = 3;
else nBitColumn = 4;
}
DWORD nBitrate = nBitrateTable[ nBitIndex ][ nBitColumn ] * 1000;
DWORD nFrequency = nFrequencyTable[ nFreqIndex ][ nVersion ];
if ( ! nFrequency ) return FALSE;
if ( nBaseBitrate )
{
if ( nBaseBitrate != nBitrate ) bVariable = TRUE;
}
else
{
nBaseBitrate = nBitrate;
nBaseFrequency = nFrequency;
}
nFrameSize = ( nLayer == 3 ) ? ( 12 * nBitrate / nFrequency + bPadding ) * 4
: ( 144 * nBitrate / nFrequency + bPadding );
if ( ! nFrameSize ) return FALSE;
nTotalBitrate += nBitrate / 1000;
nFrameCount++;
SetFilePointer( hFile, nFrameSize - 4, NULL, FILE_CURRENT );
ReadFile( hFile, &nHeader, 4, &nRead, NULL );
if ( nRead != 4 ) break;
nHeader = SWAP_LONG( nHeader );
}
else
{
nHeader <<= 8;
ReadFile( hFile, &nHeader, 1, &nRead, NULL );
if ( nRead != 1 ) break;
}
if ( ! m_pBuilder->m_bPriority )
{
m_nSleep = ( GetTickCount() - nTime ) * 3;
if ( m_nSleep > 0 ) Sleep( m_nSleep );
}
if ( ! m_pBuilder->m_bThread ) return FALSE;
}
if ( nFrameCount < 16 || ! nFrameSize ) return FALSE;
if ( bVariable )
{
nBaseBitrate = (DWORD)( nTotalBitrate / nFrameCount ) * 1000;
}
else
{
DWORD dwFilePosition = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
DWORD dwFileSize = GetFileSize( hFile, NULL );
DWORD dwMusicSize = dwFileSize - dwFilePosition - nIgnore + 4;
nFrameCount += ( dwMusicSize / nFrameSize ) - 1;
}
DWORD nFrameTime = ( nLayer == 3 ? 384 : 1152 ) * 100000 / nBaseFrequency;
DWORD nTotalTime = (DWORD)( (__int64)nFrameCount * (__int64)nFrameTime / 100000 );
CString strValue;
strValue.Format( bVariable ? _T("%lu~") : _T("%lu"), nBaseBitrate / 1000 );
pXML->AddAttribute( _T("bitrate"), strValue );
strValue.Format( _T("%lu"), nTotalTime );
pXML->AddAttribute( _T("seconds"), strValue );
strValue.Format( _T("%lu"), nBaseFrequency );
pXML->AddAttribute( _T("sampleRate"), strValue );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals version information (threaded)
BOOL CLibraryBuilderInternals::ReadVersion( LPCTSTR pszPath)
{
DWORD dwSize = GetFileVersionInfoSize( (LPTSTR)pszPath, &dwSize );
if ( dwSize <= 152 ) return FALSE;
BYTE* pBuffer = new BYTE[ dwSize ];
if ( ! GetFileVersionInfo( (LPTSTR)pszPath, NULL, dwSize, pBuffer ) )
{
delete [] pBuffer;
return FALSE;
}
WCHAR* pLanguage = (WCHAR*)pBuffer + 20 + 26 + 18 + 3;
if ( wcslen( pLanguage ) != 8 )
{
delete [] pBuffer;
return FALSE;
}
CXMLElement* pXML = new CXMLElement( NULL, _T("application") );
pXML->AddAttribute( _T("os"), _T("Windows") );
CopyVersionField( pXML, _T("title"), pBuffer, _T("ProductName") );
CopyVersionField( pXML, _T("version"), pBuffer, _T("ProductVersion"), TRUE );
CopyVersionField( pXML, _T("fileDescription"), pBuffer, _T("FileDescription") );
CopyVersionField( pXML, _T("fileVersion"), pBuffer, _T("FileVersion"), TRUE );
CopyVersionField( pXML, _T("originalFileName"), pBuffer, _T("OriginalFilename") );
CopyVersionField( pXML, _T("company"), pBuffer, _T("CompanyName") );
CopyVersionField( pXML, _T("copyright"), pBuffer, _T("LegalCopyright") );
CopyVersionField( pXML, _T("comments"), pBuffer, _T("comments") );
delete [] pBuffer;
return SubmitMetadata( _T("http://www.shareaza.com/schemas/application.xsd"), pXML );
}
BOOL CLibraryBuilderInternals::CopyVersionField(CXMLElement* pXML, LPCTSTR pszAttribute, BYTE* pBuffer, LPCTSTR pszKey, BOOL bCommaToDot)
{
CString strValue = GetVersionKey( pBuffer, pszKey );
if ( strValue.IsEmpty() ) return FALSE;
if ( bCommaToDot )
{
for ( int nPos = -1 ; ( nPos = strValue.Find( _T(", ") ) ) >= 0 ; )
{
strValue = strValue.Left( nPos ) + '.' + strValue.Mid( nPos + 2 );
}
}
pXML->AddAttribute( pszAttribute, strValue );
return TRUE;
}
CString CLibraryBuilderInternals::GetVersionKey(BYTE* pBuffer, LPCTSTR pszKey)
{
CString strKey, strValue;
WCHAR* pLanguage = (WCHAR*)pBuffer + 20 + 26 + 18 + 3;
strKey = _T("\\StringFileInfo\\");
strKey += pLanguage;
strKey += _T("\\");
strKey += pszKey;
BYTE* pValue = NULL;
DWORD dwSize = 0;
if ( ! VerQueryValue( pBuffer, (LPTSTR)(LPCTSTR)strKey, (void**)&pValue, (UINT*)&dwSize ) )
return strValue;
if ( pValue[1] )
strValue = (LPCSTR)pValue;
else
strValue = (LPCTSTR)pValue;
return strValue;
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals JPEG (threaded)
BOOL CLibraryBuilderInternals::ReadJPEG( HANDLE hFile)
{
DWORD nRead = 0;
WORD wMagic = 0;
BYTE nByte = 0;
SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
ReadFile( hFile, &wMagic, 2, &nRead, NULL );
if ( nRead != 2 || wMagic != 0xD8FF ) return SubmitCorrupted();
BYTE nBits = 0, nComponents = 0;
WORD nWidth = 0, nHeight = 0;
CString strComment;
for ( DWORD nSeek = 512 ; nSeek > 0 ; nSeek-- )
{
ReadFile( hFile, &nByte, 1, &nRead, NULL );
if ( nRead != 1 ) return FALSE;
if ( nByte != 0xFF ) continue;
while ( nByte == 0xFF )
{
ReadFile( hFile, &nByte, 1, &nRead, NULL );
if ( nRead != 1 ) return FALSE;
}
ReadFile( hFile, &wMagic, 2, &nRead, NULL );
wMagic = ( wMagic >> 8 ) | ( wMagic << 8 );
if ( nRead != 2 || wMagic < 2 ) return FALSE;
switch ( nByte )
{
case 0xC0: case 0xC1: case 0xC2: case 0xC3: case 0xC5: case 0xC6: case 0xC7:
case 0xC9: case 0xCA: case 0xCB: case 0xCD: case 0xCE: case 0xCF:
ReadFile( hFile, &nBits, 1, &nRead, NULL );
if ( nRead != 1 ) return FALSE;
ReadFile( hFile, &nHeight, 2, &nRead, NULL );
if ( nRead != 2 ) return FALSE;
nHeight = ( nHeight >> 8 ) | ( nHeight << 8 );
ReadFile( hFile, &nWidth, 2, &nRead, NULL );
if ( nRead != 2 ) return FALSE;
nWidth = ( nWidth >> 8 ) | ( nWidth << 8 );
ReadFile( hFile, &nComponents, 1, &nRead, NULL );
if ( nRead != 1 ) return FALSE;
if ( wMagic < 8 ) return FALSE;
SetFilePointer( hFile, wMagic - 8, NULL, FILE_CURRENT );
break;
case 0xFE: case 0xEC:
if ( wMagic > 2 )
{
CBuffer pComment;
pComment.EnsureBuffer( wMagic - 2 );
pComment.m_nLength = (DWORD)wMagic - 2;
ReadFile( hFile, pComment.m_pBuffer, wMagic - 2, &nRead, NULL );
strComment = pComment.ReadString( nRead );
}
break;
case 0xD9: case 0xDA:
nSeek = 1;
break;
default:
SetFilePointer( hFile, wMagic - 2, NULL, FILE_CURRENT );
break;
}
}
if ( nWidth == 0 || nHeight == 0 ) return FALSE;
strComment.TrimLeft();
strComment.TrimRight();
for ( int nChar = 0 ; nChar < strComment.GetLength() ; nChar++ )
{
if ( strComment[ nChar ] < 32 ) strComment.SetAt( nChar, '?' );
}
CXMLElement* pXML = new CXMLElement( NULL, _T("image") );
CString strItem;
strItem.Format( _T("%lu"), nWidth );
pXML->AddAttribute( _T("width"), strItem );
strItem.Format( _T("%lu"), nHeight );
pXML->AddAttribute( _T("height"), strItem );
if ( nComponents == 3 ) pXML->AddAttribute( _T("colors"), _T("16.7M") );
else if ( nComponents == 1 ) pXML->AddAttribute( _T("colors"), _T("Greyscale") );
if ( strComment.GetLength() ) pXML->AddAttribute( _T("description"), strComment );
return SubmitMetadata( CSchema::uriImage, pXML );
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals GIF (threaded)
BOOL CLibraryBuilderInternals::ReadGIF( HANDLE hFile)
{
CHAR szMagic[6];
DWORD nRead;
SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
ReadFile( hFile, szMagic, 6, &nRead, NULL );
if ( nRead != 6 || ( strncmp( szMagic, "GIF87a", 6 ) && strncmp( szMagic, "GIF89a", 6 ) ) )
return SubmitCorrupted();
WORD nWidth, nHeight;
ReadFile( hFile, &nWidth, 2, &nRead, NULL );
if ( nRead != 2 || nWidth == 0 ) return FALSE;
ReadFile( hFile, &nHeight, 2, &nRead, NULL );
if ( nRead != 2 || nHeight == 0 ) return FALSE;
CXMLElement* pXML = new CXMLElement( NULL, _T("image") );
CString strItem;
strItem.Format( _T("%lu"), nWidth );
pXML->AddAttribute( _T("width"), strItem );
strItem.Format( _T("%lu"), nHeight );
pXML->AddAttribute( _T("height"), strItem );
pXML->AddAttribute( _T("colors"), _T("256") );
return SubmitMetadata( _T("http://www.shareaza.com/schemas/image.xsd"), pXML );
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals PNG (threaded)
BOOL CLibraryBuilderInternals::ReadPNG( HANDLE hFile)
{
BYTE nMagic[8];
DWORD nRead;
if ( GetFileSize( hFile, NULL ) < 33 ) return SubmitCorrupted();
SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
ReadFile( hFile, nMagic, 8, &nRead, NULL );
if ( nRead != 8 ) return SubmitCorrupted();
if ( nMagic[0] != 137 || nMagic[1] != 80 || nMagic[2] != 78 ) return SubmitCorrupted();
if ( nMagic[3] != 71 || nMagic[4] != 13 || nMagic[5] != 10 ) return SubmitCorrupted();
if ( nMagic[6] != 26 || nMagic[7] != 10 ) return SubmitCorrupted();
DWORD nLength, nIHDR;
ReadFile( hFile, &nLength, 4, &nRead, NULL ); nLength = SWAP_LONG( nLength );
if ( nRead != 4 || nLength < 10 ) return FALSE;
ReadFile( hFile, &nIHDR, 4, &nRead, NULL );
if ( nRead != 4 || nIHDR != 'RDHI' ) return FALSE;
DWORD nWidth, nHeight;
BYTE nBits, nColors;
ReadFile( hFile, &nWidth, 4, &nRead, NULL ); nWidth = SWAP_LONG( nWidth );
if ( nRead != 4 || nWidth <= 0 || nWidth > 0xFFFF ) return FALSE;
ReadFile( hFile, &nHeight, 4, &nRead, NULL ); nHeight = SWAP_LONG( nHeight );
if ( nRead != 4 || nHeight <= 0 || nHeight > 0xFFFF ) return FALSE;
ReadFile( hFile, &nBits, 1, &nRead, NULL );
if ( nRead != 1 ) return FALSE;
ReadFile( hFile, &nColors, 1, &nRead, NULL );
if ( nRead != 1 ) return FALSE;
CXMLElement* pXML = new CXMLElement( NULL, _T("image") );
CString strItem;
strItem.Format( _T("%lu"), nWidth );
pXML->AddAttribute( _T("width"), strItem );
strItem.Format( _T("%lu"), nHeight );
pXML->AddAttribute( _T("height"), strItem );
/*
if ( nColors == 2 || nColors == 4 )
{
pXML->AddAttribute( _T("colors"), _T("Greyscale") );
}
else
*/
{
switch ( nBits )
{
case 1:
pXML->AddAttribute( _T("colors"), _T("2") );
break;
case 2:
pXML->AddAttribute( _T("colors"), _T("4") );
break;
case 4:
pXML->AddAttribute( _T("colors"), _T("16") );
break;
case 8:
pXML->AddAttribute( _T("colors"), _T("256") );
break;
case 16:
pXML->AddAttribute( _T("colors"), _T("64K") );
break;
}
}
return SubmitMetadata( _T("http://www.shareaza.com/schemas/image.xsd"), pXML );
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals BMP (threaded)
BOOL CLibraryBuilderInternals::ReadBMP( HANDLE hFile)
{
BITMAPFILEHEADER pBFH;
BITMAPINFOHEADER pBIH;
DWORD nRead;
if ( GetFileSize( hFile, NULL ) < sizeof(pBFH) + sizeof(pBIH) ) return SubmitCorrupted();
SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
ReadFile( hFile, &pBFH, sizeof(pBFH), &nRead, NULL );
if ( nRead != sizeof(pBFH) || pBFH.bfType != 'MB' ) return SubmitCorrupted();
ReadFile( hFile, &pBIH, sizeof(pBIH), &nRead, NULL );
if ( nRead != sizeof(pBIH) || pBIH.biSize != sizeof(pBIH) ) return FALSE;
CXMLElement* pXML = new CXMLElement( NULL, _T("image") );
CString strItem;
strItem.Format( _T("%lu"), pBIH.biWidth );
pXML->AddAttribute( _T("width"), strItem );
strItem.Format( _T("%lu"), pBIH.biHeight );
pXML->AddAttribute( _T("height"), strItem );
switch ( pBIH.biBitCount )
{
case 4:
pXML->AddAttribute( _T("colors"), _T("16") );
break;
case 8:
pXML->AddAttribute( _T("colors"), _T("256") );
break;
case 24:
pXML->AddAttribute( _T("colors"), _T("16.7M") );
break;
}
return SubmitMetadata( _T("http://www.shareaza.com/schemas/image.xsd"), pXML );
}
//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals ASF (threaded)
static const CLSID asfHeader1 =
{ 0x75B22630, 0x668E, 0x11CF, { 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C } };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -