📄 id3.c
字号:
//****************************************************************************//// ID3.C - ID3v1 and ID3v2.3.0 tag decoder.//// Copyright (c) 2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"//****************************************************************************//// ID3IsV1Tag determines if the given sequence of bytes constitutes an ID3v1// tag.////****************************************************************************unsigned longID3IsV1Tag(unsigned char *pucBuffer){ // // The first three characters are "TAG" for an ID3v1 tag. // if((pucBuffer[0] == 'T') && (pucBuffer[1] == 'A') && (pucBuffer[2] == 'G')) { return(1); } // // This is not an ID3v1 tag. // return(0);}//****************************************************************************//// ID3IsV2Tag determines if the given sequence of bytes constitutes an ID3v2// tag. The length of the tag is returned if it is a valid tag.////****************************************************************************unsigned longID3IsV2Tag(unsigned char *pucBuffer){ // // The first three bytes of the tag should be "ID3". // if((pucBuffer[0] != 'I') || (pucBuffer[1] != 'D') || (pucBuffer[2] != '3')) { return(0); } // // The next byte should be the value 3 (i.e. we support ID3v2.3.0). // if(pucBuffer[3] != 3) { return(0); } // // The next byte should be less than 0xff. // if(pucBuffer[4] == 0xff) { return(0); } // // We don't care about the next byte. The following four bytes should be // less than 0x80. // if((pucBuffer[6] >= 0x80) || (pucBuffer[7] >= 0x80) || (pucBuffer[8] >= 0x80) || (pucBuffer[9] >= 0x80)) { return(0); } // // Return the length of the ID3v2 tag. // return((pucBuffer[6] << 21) | (pucBuffer[7] << 14) | (pucBuffer[8] << 7) | pucBuffer[9]);}//****************************************************************************//// ID3UnsynchronizeTag performs an unsynchronization of the portion of the// ID3v2 tag current read into memory.////****************************************************************************static voidID3UnsynchronizeTag(unsigned char *pucBuffer, unsigned long ulStart, unsigned long *pulValid){ unsigned long ulPos; // // Go through all the bytes in the buffer, replacing 0xff 0x00 with 0xff. // for(ulPos = ulStart; ulPos < *pulValid; ulPos++) { // // See if the current byte pair is 0xff 0x00. // if((pucBuffer[ulPos] == 0xff) && (pucBuffer[ulPos + 1] == 0x00)) { // // We need to replace this with 0xff, so simply copy the remainder // of the buffer down. // memcpy(pucBuffer + ulPos + 1, pucBuffer + ulPos + 2, *pulValid - ulPos - 2); // // There is one less valid byte of data in the buffer. // (*pulValid)--; } }}//****************************************************************************//// ID3GetMoreTagData reads the next page of data from the file.////****************************************************************************static voidID3GetMoreTagData(tFile *pFile, unsigned char *pucBuffer, unsigned long *pulStart, unsigned long *pulValid, unsigned long *pulTagLength, unsigned long ulFlags){ unsigned long ulTemp; // // If the start pointer is past the end of the valid data in the buffer, // then read in data until that is not the case. // while(*pulStart >= *pulValid) { // // Copy the last four bytes of data to the beginning of the buffer. // memcpy(pucBuffer, pucBuffer + *pulValid - 4, 4); // // Update the starting position and count of valid bytes in the buffer. // *pulStart -= *pulValid - 4; *pulValid = 4; // // Read the next 512 bytes from the file. // ulTemp = FSRead(pFile, pucBuffer + 4, 512); // // Update the remaining length of the tag. // if(ulTemp < *pulTagLength) { // // The remaining data in the tag is greater than the data just // read, so decrement the remaining tag length by the number of // bytes just read. // *pulTagLength -= ulTemp; } else { // // The remaining data in the tag is entirely contained in the data // just read, so update the length of the data just read to be the // number of bytes remaining in the tag, and set the remaining // length of the tag to zero. // ulTemp = *pulTagLength; *pulTagLength = 0; } // // If necessary, unsynchronize this portion of the tag. // if(ulFlags & 0x80) { // // We need to unsynchronize across the boundary of where we // performed the to reads of data, so increment the count of new // bytes by one. // ulTemp++; // // Unsynchronize the new portion of the file, including the // previously read byte. // ID3UnsynchronizeTag(pucBuffer, 3, &ulTemp); // // Decrement the count of new bytes by one. // ulTemp--; } // // Add the number of bytes read to the count of valid bytes. // *pulValid += ulTemp; } // // Determine the byte that will be at the beginning of the buffer. // ulTemp = *pulValid - ((*pulValid - *pulStart + 3) & ~3); // // Copy the remaining data to the beginning of the buffer. // memcpy(pucBuffer, pucBuffer + ulTemp, *pulValid - ulTemp); // // Update the starting position and count of valid bytes in the buffer. // *pulStart -= ulTemp; *pulValid -= ulTemp; // // Read the next 512 bytes from the file. // ulTemp = FSRead(pFile, pucBuffer + *pulValid, 512); // // Update the remaining length of the tag. // if(ulTemp < *pulTagLength) { // // The remaining data in the tag is greater than the data just read, // so decrement the remaining tag length by the number of bytes just // read. // *pulTagLength -= ulTemp; } else { // // The remaining data in the tag is entirely contained in the data just // read, so update the length of the data just read to be the number of // bytes remaining in the tag, and set the remaining length of the tag // to zero. // ulTemp = *pulTagLength; *pulTagLength = 0; } // // If necessary, unsynchronize this portion of the tag. // if(ulFlags & 0x80) { // // We need to unsynchronize across the boundary of where we performed // the to reads of data, so increment the count of new bytes by one. // ulTemp++; // // Unsynchronize the new portion of the file, including the previously // read byte. // ID3UnsynchronizeTag(pucBuffer, *pulValid - 1, &ulTemp); // // Decrement the count of new bytes by one. // ulTemp--; } // // Increment the count of valid bytes by the number just read. // *pulValid += ulTemp;}//****************************************************************************//// ID3FindTags determines if any ID3 tags are present in the given file and// updates the start position and/or length of the data based on the presence// of the tags.////****************************************************************************voidID3FindTags(tFile *pFile, unsigned long *pulStart, unsigned long *pulLength, unsigned char *pucBuffer){ unsigned long ulLength; // // First, see if we have an ID3v1 tag, which appears at the end of the // file. Seek to the end of the file minus 128 bytes. // FSSeek(pFile, (*pulStart + *pulLength - 128) & ~511); // // Read 1K of data from the file. // FSRead(pFile, pucBuffer, 1024); // // See if this is an ID3v1 tag. // if(ID3IsV1Tag(pucBuffer + ((*pulStart + *pulLength - 128) & 511))) { // // There is an ID3v1 tag at the end of the file, so remove the 128 // bytes in the tag from the length of the file. // *pulLength -= 128; } // // Now, see if we have an ID3v2 tag. Seek to the beginning of the file // data. // FSSeek(pFile, *pulStart & ~511); // // Read 1K of data from the file. // FSRead(pFile, pucBuffer, 1024); // // See if this is an ID3v2 tag. // if((ulLength = ID3IsV2Tag(pucBuffer + (*pulStart & 511))) != 0) { // // There is an ID3v2 tag at the beginning of the file. The actual file // data starts after the ID3v2 tag, and the length of the file is // decremented by the length of the tag. // *pulStart += ulLength + 10; *pulLength -= ulLength + 10; }}//****************************************************************************//// ID3GetTagValue reads the value of either the artist or the song title from// the ID3 tag.////****************************************************************************unsigned longID3GetTagValue(tFile *pFile, unsigned long ulStart, unsigned long ulLength, unsigned char *pucBuffer, char *pcTag, unsigned short *pusValue,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -