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

📄 id3_support.cpp

📁 flash xmp sdk,flash官方SDK
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			if ( (bEncoding == 0) || (bEncoding == 3) ) {				dwOffset += (strlen ( &strData[3] ) + 1);	// Skip the descriptor and nul.			} else {				UTF16Unit* u16Ptr = (UTF16Unit*) (&strData[3]);				for ( ; *u16Ptr != 0; ++u16Ptr ) dwOffset += 2;	// Skip the descriptor.				dwOffset += 2;	// Skip the nul also.			}			if ( dwOffset >= dwBufferSize ) return false;			dwBufferSize -= dwOffset;			sdPos = dwOffset;			#if Trace_ID3_Support				fprintf ( stderr, "    COMM frame, dwOffset %d\n", dwOffset );			#endif		}		// Encoding translation		switch ( bEncoding ) {			case 1:	// UTF-16 with a BOM. (Might be missing for empty string.)			case 2:	// Big endian UTF-16 with no BOM.				{					bool bigEndian = true;	// Assume big endian if no BOM.					UTF16Unit* u16Ptr = (UTF16Unit*) &strData[sdPos];					if ( GetUns16BE ( u16Ptr ) == 0xFEFF ) {						++u16Ptr;	// Don't translate the BOM.					} else if ( GetUns16BE ( u16Ptr ) == 0xFFFE ) {						bigEndian = false;						++u16Ptr;	// Don't translate the BOM.					}										size_t u16Len = 0;	// Count the UTF-16 units, not bytes.					for ( UTF16Unit* temp = u16Ptr; *temp != 0; ++temp ) ++u16Len;					std::string utf8Str;					FromUTF16 ( u16Ptr, u16Len, &utf8Str, bigEndian );					if ( utf8Str.size() >= (sizeof(strData) - sdPos) ) return false;					strcpy ( &strData[sdPos], utf8Str.c_str() );	// AUDIT: Protected by the above check.				}				break;			case 0: // ISO Latin-1 (8859-1).				{					std::string utf8Str;					char* localPtr  = &strData[sdPos];					size_t localLen = dwBufferSize;					ReconcileUtils::Latin1ToUTF8 ( localPtr, localLen, &utf8Str );					if ( utf8Str.size() >= (sizeof(strData) - sdPos) ) return false;					strcpy ( &strData[sdPos], utf8Str.c_str() );	// AUDIT: Protected by the above check.				}				break;			case 3: // UTF-8			default:				// Handled appropriately				break;		}		char * strTemp = &strData[sdPos];				if ( strcmp ( strFrame, "TCON" ) == 0 ) {			char str[TAG_MAX_SIZE];			str[0] = 0;			if ( strlen ( &strData[sdPos] ) >= sizeof(str) ) return false;			strcpy ( str, &strData[sdPos] );	// AUDIT: Protected by the above check.			#if Trace_ID3_Support				fprintf ( stderr, "    TCON frame, first char '%c'\n", str[0] );			#endif			// Genre: let's get the "string" value			if ( str[0] == '(' ) {				int iGenre = atoi(str+1);				if ( (iGenre > 0) && (iGenre < 127) ) {					strTemp = Genres[iGenre];				} else {					strTemp = Genres[12];				}			} else {				// Text, let's "try" to find it anyway				int i = 0;				for ( i=0; i < 127; ++i ) {					if ( stricmp ( str, Genres[i] ) == 0 ) {						strTemp = Genres[i]; // Found, let's use the one in the list						break;					}				}				if ( i == 127 ) strTemp = Genres[12]; // Not found			}		}		#if Trace_ID3_Support			fprintf ( stderr, "    Have data, length %d, \"%s\"\n", strlen(strTemp), strTemp );		#endif		if ( strlen(strTemp) >= dwSizeIn ) return false;		strcpy ( buffer, strTemp );	// AUDIT: Protected by the above check.	}	return true;}// =================================================================================================bool AddXMPTagToID3Buffer ( char * strCur, unsigned long * pdwCurOffset, unsigned long dwMaxSize, XMP_Uns8 bVersion,							char *strFrameName, const char * strXMPTagTemp, unsigned long dwXMPLengthTemp ){	char strGenre[64];	const char * strXMPTag = strXMPTagTemp;	XMP_Int32 dwCurOffset = *pdwCurOffset;	XMP_Uns8 bEncoding = 0;	long dwXMPLength = dwXMPLengthTemp;	if ( dwXMPLength == 0 ) return false;	if ( strcmp ( strFrameName, "TCON" ) == 0 ) {		// Genre: we need to get the number back...		int iFound = 12;		for ( int i=0; i < 127; ++i ) {			if ( stricmp ( strXMPTag, Genres[i] ) == 0 ) {				iFound = i; // Found				break;			}		}		snprintf ( strGenre, sizeof(strGenre), "(%d)", iFound );	// AUDIT: Using sizeof(strGenre) is safe.		strXMPTag = strGenre;		dwXMPLength = strlen(strXMPTag);	}	// Stick with the ID3v2.3 encoding choices, they are a proper subset of ID3v2.4.	//	0 - ISO Latin-1	//	1 - UTF-16 with BOM	// For 3rd party reliability we always write UTF-16 as little endian. For example, Windows	// Media Player fails to honor the BOM, it assumes little endian.	std::string tempLatin1, tempUTF8;	ReconcileUtils::UTF8ToLatin1 ( strXMPTag, dwXMPLength, &tempLatin1 );	ReconcileUtils::Latin1ToUTF8 ( tempLatin1.data(), tempLatin1.size(), &tempUTF8 );	if ( ((size_t)dwXMPLength != tempUTF8.size()) || (memcmp ( strXMPTag, tempUTF8.data(), dwXMPLength ) != 0) ) {		bEncoding = 1;	// Will convert to UTF-16 later.	} else {		strXMPTag   = tempLatin1.c_str();	// Use the Latin-1 encoding for output.		dwXMPLength = tempLatin1.size();	}	std::string strUTF16;	if ( bEncoding == 1 ) {		ToUTF16 ( (UTF8Unit*)strXMPTag, dwXMPLength, &strUTF16, false /* little endian */ );		dwXMPLength = strUTF16.size() + 2;	// ! Include the (to be inserted) BOM in the count.	}	//		Frame Structure    //		Frame ID      $xx xx xx xx  (four characters)    //		Size      4 * %0xxxxxxx     <<--- IMPORTANT NOTE: This is true only in v4.0 (v3.0 uses a UInt32)    //		Flags         $xx xx	//		Encoding	  $xx (Not included in the frame header)	//		Special case: "COMM" which we have to include "XXX\0" in front of it (also not included in the frame header)	unsigned long dwFrameSize = dwXMPLength + 1; // 1 == Encoding;	bool fCOMM = (strcmp ( strFrameName, "COMM" ) == 0);	if ( fCOMM ) {		dwFrameSize += 3;	// The "XXX" language part.		dwFrameSize += ((bEncoding == 0) ? 1 : 4 );	// The empty descriptor string.	}		if ( (dwCurOffset + k_dwFrameHeaderSize + dwFrameSize) > dwMaxSize ) return false;	unsigned long dwCalculated = CalculateSize ( bVersion, dwFrameSize );	// FrameID	if ( (dwMaxSize - dwCurOffset) < 4 ) return false;	memcpy ( strCur+dwCurOffset, strFrameName, 4 );	// AUDIT: Protected by the above check.	dwCurOffset += 4;	// Frame Size - written as big endian	strCur[dwCurOffset] = (char)(dwCalculated >> 24);	++dwCurOffset;	strCur[dwCurOffset] = (char)((dwCalculated >> 16) & 0xFF);	++dwCurOffset;	strCur[dwCurOffset] = (char)((dwCalculated >> 8) & 0xFF);	++dwCurOffset;	strCur[dwCurOffset] = (char)(dwCalculated & 0xFF);	++dwCurOffset;	// Flags	strCur[dwCurOffset] = 0;	++dwCurOffset;	strCur[dwCurOffset] = 0;	++dwCurOffset;	// Encoding	strCur[dwCurOffset] = bEncoding;	++dwCurOffset;	// COMM extras: XXX language and empty encoded descriptor string.	if ( fCOMM ) {		if ( (dwMaxSize - dwCurOffset) < 3 ) return false;		memcpy ( strCur+dwCurOffset, "XXX", 3 );	// AUDIT: Protected by the above check.		dwCurOffset += 3;		if ( bEncoding == 0 ) {			strCur[dwCurOffset] = 0;			++dwCurOffset;		} else {			strCur[dwCurOffset] = 0xFF;			++dwCurOffset;			strCur[dwCurOffset] = 0xFE;			++dwCurOffset;			strCur[dwCurOffset] = 0;			++dwCurOffset;			strCur[dwCurOffset] = 0;			++dwCurOffset;		}	}	if ( bEncoding == 1 ) {		// Add the BOM "FFFE"		strCur[dwCurOffset] = 0xFF;		++dwCurOffset;		strCur[dwCurOffset] = 0xFE;		++dwCurOffset;		dwXMPLength -= 2;	// The BOM was included above.		// Copy the Unicode data		if ( (long)(dwMaxSize - dwCurOffset) < dwXMPLength ) return false;		memcpy ( strCur+dwCurOffset, strUTF16.data(), dwXMPLength );	// AUDIT: Protected by the above check.		dwCurOffset += dwXMPLength;	} else {		// Copy the data		if ( (long)(dwMaxSize - dwCurOffset) < dwXMPLength ) return false;		memcpy ( strCur+dwCurOffset, strXMPTag, dwXMPLength );	// AUDIT: Protected by the above check.		dwCurOffset += dwXMPLength;	}	*pdwCurOffset = dwCurOffset;	return true;}// =================================================================================================static void OffsetAudioData ( LFA_FileRef inFileRef, XMP_Int64 audioOffset, XMP_Int64 oldAudioBase ){	enum { kBuffSize = 64*1024 };	XMP_Uns8 buffer [kBuffSize];	const XMP_Int64 posEOF = LFA_Measure ( inFileRef );	XMP_Int64 posCurrentCopy;	// ! Must be a signed type!	posCurrentCopy = posEOF;	while ( posCurrentCopy >= (oldAudioBase + kBuffSize) ) {		posCurrentCopy -= kBuffSize;	// *** Xcode 2.3 seemed to generate bad code using a for loop.		LFA_Seek ( inFileRef, posCurrentCopy, SEEK_SET );		LFA_Read ( inFileRef, buffer, kBuffSize );		LFA_Seek ( inFileRef, (posCurrentCopy + audioOffset), SEEK_SET );		LFA_Write ( inFileRef, buffer, kBuffSize );	}		if ( posCurrentCopy != oldAudioBase ) {		XMP_Uns32 remainder = (XMP_Uns32) (posCurrentCopy - oldAudioBase);		XMP_Assert ( remainder < kBuffSize );		LFA_Seek ( inFileRef, oldAudioBase, SEEK_SET );		LFA_Read ( inFileRef, buffer, remainder );		LFA_Seek ( inFileRef, (oldAudioBase + audioOffset), SEEK_SET );		LFA_Write ( inFileRef, buffer, remainder );	}}// =================================================================================================bool SetMetaData ( LFA_FileRef inFileRef, char* strXMPPacket, unsigned long dwXMPPacketSize,                   char* strLegacyFrames, unsigned long dwFullLegacySize, bool fRecon ){	// The ID3 section layout:	//	ID3 header, 10 bytes	//	Unrecognized ID3 frames	//	Legacy ID3 metadata frames (artist, album, genre, etc.)	//	XMP frame, content is "XMP\0" plus the packet	//	padding	// ID3 Buffer vars	const unsigned long kiMaxBuffer = 100*1000;	char szID3Buffer [kiMaxBuffer];	// Must be enough for the ID3 header, unknown ID3 frames, and legacy ID3 metadata.	unsigned long id3BufferLen = 0;	// The amount of stuff currently in the buffer.	unsigned long dwOldID3ContentSize = 0;	// The size of the existing ID3 content (not counting the header).	unsigned long dwNewID3ContentSize = 0;	// The size of the updated ID3 content (not counting the header).		unsigned long newPadSize = 0;	XMP_Uns8 bMajorVersion = 3;	bool fFoundID3 = FindID3Tag ( inFileRef, dwOldID3ContentSize, bMajorVersion );	if ( (bMajorVersion > 4) || (bMajorVersion < 3) ) return false;	// Not supported	// Now that we know the version of the ID3 tag, let's format the size of the XMP frame.	#define k_XMPPrefixSize	(k_dwFrameHeaderSize + k_dwXMPLabelSize)	char szXMPPrefix [k_XMPPrefixSize] = { 'P', 'R', 'I', 'V', 0, 0, 0, 0, 0, 0, 'X', 'M', 'P', 0 };	unsigned long dwXMPContentSize = k_dwXMPLabelSize + dwXMPPacketSize;	unsigned long dwFullXMPFrameSize = k_dwFrameHeaderSize + dwXMPContentSize;	unsigned long dwFormattedTemp = CalculateSize ( bMajorVersion, dwXMPContentSize );	szXMPPrefix[4] = (char)(dwFormattedTemp >> 24);	szXMPPrefix[5] = (char)((dwFormattedTemp >> 16) & 0xFF);	szXMPPrefix[6] = (char)((dwFormattedTemp >> 8) & 0xFF);	szXMPPrefix[7] = (char)(dwFormattedTemp & 0xFF);	// Set up the ID3 buffer with the ID3 header and any existing unrecognized ID3 frames.	if ( ! fFoundID3 ) {		// Case 1 - No id3v2 tag: Create the tag with the XMP frame.		// Create the tag		//     ID3v2/file identifier      "ID3"		//     ID3v2 version              $03 00		//     ID3v2 flags                %abcd0000		//     ID3v2 size             4 * %0xxxxxxx		XMP_Assert ( dwOldID3ContentSize == 0 );				char szID3Header [k_dwTagHeaderSize] = { 'I', 'D', '3', 3, 0, 0, 0, 0, 0, 0 };		// Copy the ID3 header		if ( sizeof(szID3Buffer) < k_dwTagHeaderSize ) return false;		memcpy ( szID3Buffer, szID3Header, k_dwTagHeaderSize );	// AUDIT: Protected by the above check.		id3BufferLen = k_dwTagHeaderSize;		newPadSize = 100;		dwNewID3ContentSize = dwFullLegacySize + dwFullXMPFrameSize + newPadSize;	} else { 		// Case 2 - id3v2 tag is present		// 1. Copy all the unknown tags		// 2. Make the rest padding (to be used right there).		if ( (k_dwFrameHeaderSize + dwOldID3ContentSize) > kiMaxBuffer ) {			// The ID3Buffer is not big enough to fit the id3v2 tag... let's bail...			return false;		}		LoadTagHeaderAndUnknownFrames ( inFileRef, szID3Buffer, fRecon, id3BufferLen );				unsigned long spareLen = (k_dwFrameHeaderSize + dwOldID3ContentSize) - id3BufferLen;				if ( spareLen >= (dwFullLegacySize + dwFullXMPFrameSize) ) {					// The exising ID3 header can hold the update.			dwNewID3ContentSize = dwOldID3ContentSize;			newPadSize = spareLen - (dwFullLegacySize + dwFullXMPFrameSize);				} else {					// The existing ID3 header is too small, it will have to grow.			newPadSize = 100;			dwNewID3ContentSize = (id3BufferLen - k_dwTagHeaderSize) +								  dwFullLegacySize + dwFullXMPFrameSize + newPadSize;				}	}	

⌨️ 快捷键说明

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