/// <summary> /// Reads the ID3v1 tag using specified code page for text encoding. /// </summary> /// <param name="inputStream">the input stream (i.e. the file.)</param> /// <param name="codePage">The code page for text encoding.</param> /// <returns>An ID3v1 container.</returns> public Id3V1Tag Read(Stream inputStream, int codePage) { if (!inputStream.CanSeek) { var ex = new Id3TagException("Cannot read ID3v1 tag because the stream does not support seek."); Logger.LogError(ex); throw ex; } if (inputStream.Length < 128) { var ex = new Id3IOException("Cannot read ID3v1 tag because the stream is too short"); Logger.LogError(ex); throw ex; } // // Read the last 128 Bytes from the stream (ID3v1 Position) // var tagBytes = new byte[128]; inputStream.Seek(-128, SeekOrigin.End); inputStream.Read(tagBytes, 0, 128); bool isValidTag = CheckID(tagBytes); if (!isValidTag) { var ex = new Id3HeaderNotFoundException("TAG header not found"); Logger.LogError(ex); throw ex; } Id3V1Tag v1Tag = ExtractTag(tagBytes, codePage); return v1Tag; }
private static int AnalyseHeader(byte[] headerBytes, Id3TagInfo tagInfo) { // Check ID3 pattern bool id3PatternFound = (headerBytes[0] == 0x49) && (headerBytes[1] == 0x44) && (headerBytes[2] == 0x33); if (!id3PatternFound) { var ex = new Id3HeaderNotFoundException(); Logger.LogError(ex); throw ex; } int majorVersion = Convert.ToInt32(headerBytes[3]); int revision = Convert.ToInt32(headerBytes[4]); byte flagByte = headerBytes[5]; var sizeBytes = new byte[4]; // Analyse the header... tagInfo.MajorVersion = majorVersion; tagInfo.Revision = revision; bool unsynchronisationFlag = (flagByte & 0x80) == 0x80; bool extendedHeaderFlag = (flagByte & 0x40) == 0x40; bool experimentalFlag = (flagByte & 0x20) == 0x20; tagInfo.Unsynchronised = unsynchronisationFlag; tagInfo.ExtendedHeaderAvailable = extendedHeaderFlag; tagInfo.Experimental = experimentalFlag; if (majorVersion == 4) { // // ID3V2.4 tag found! check for footer. // bool footerFlag = (flagByte & 0x10) == 0x10; tagInfo.HasFooter = footerFlag; } Array.Copy(headerBytes, 6, sizeBytes, 0, 4); int size = Utils.Convert7BitEncodedToInt32(sizeBytes); return size; }