private byte[] GetTagBytes(Id3Tag tag) { var bytes = new List <byte>(); bytes.AddRange(AsciiEncoding.GetBytes("ID3")); bytes.AddRange(new byte[] { 3, 0, 0 }); foreach (Id3Frame frame in tag.Frames) { if (frame.IsAssigned) { FrameHandler mapping = FrameHandlers[frame.GetType()]; if (mapping != null) { byte[] frameBytes = mapping.Encoder(frame); bytes.AddRange(AsciiEncoding.GetBytes(GetFrameIdFromFrame(frame))); bytes.AddRange(SyncSafeNumber.EncodeNormal(frameBytes.Length)); bytes.AddRange(new byte[] { 0, 0 }); bytes.AddRange(frameBytes); } } } int framesSize = bytes.Count - 6; bytes.InsertRange(6, SyncSafeNumber.EncodeSafe(framesSize)); return(bytes.ToArray()); }
private static int GetTagSize(Stream stream) { stream.Seek(6, SeekOrigin.Begin); var sizeBytes = new byte[4]; stream.Read(sizeBytes, 0, 4); int tagSize = SyncSafeNumber.DecodeSafe(sizeBytes, 0, 4) + 10; return(tagSize); }
internal override byte[] GetTagBytes(Stream stream) { if (!HasTag(stream)) { return(null); } var sizeBytes = new byte[4]; stream.Seek(6, SeekOrigin.Begin); stream.Read(sizeBytes, 0, 4); int tagSize = SyncSafeNumber.DecodeSafe(sizeBytes, 0, 4); var tagBytes = new byte[tagSize + 10]; stream.Seek(0, SeekOrigin.Begin); stream.Read(tagBytes, 0, tagBytes.Length); return(tagBytes); }
internal override Id3Tag ReadTag(Stream stream) { if (!HasTag(stream)) { return(null); } var tag = new Id3Tag { MajorVersion = 2, MinorVersion = 3, Family = Id3TagFamily.Version2x, IsSupported = true, }; stream.Seek(4, SeekOrigin.Begin); var headerBytes = new byte[6]; stream.Read(headerBytes, 0, 6); var headerContainer = new Id3v2Header(); tag.AdditionalData = headerContainer; byte flags = headerBytes[1]; var header = new Id3v2StandardHeader { Revision = headerBytes[0], Unsyncronization = (flags & 0x80) > 0, ExtendedHeader = (flags & 0x40) > 0, Experimental = (flags & 0x20) > 0 }; headerContainer.Header = header; int tagSize = SyncSafeNumber.DecodeSafe(headerBytes, 2, 4); var tagData = new byte[tagSize]; stream.Read(tagData, 0, tagSize); int currentPos = 0; if (header.ExtendedHeader) { SyncSafeNumber.DecodeSafe(tagData, currentPos, 4); currentPos += 4; var extendedHeader = new Id3v2ExtendedHeader { PaddingSize = SyncSafeNumber.DecodeNormal(tagData, currentPos + 2, 4) }; if ((tagData[currentPos] & 0x80) > 0) { extendedHeader.Crc32 = SyncSafeNumber.DecodeNormal(tagData, currentPos + 6, 4); currentPos += 10; } else { currentPos += 6; } headerContainer.ExtendedHeader = extendedHeader; } while (currentPos < tagSize && tagData[currentPos] != 0x00) { string frameId = AsciiEncoding.GetString(tagData, currentPos, 4); currentPos += 4; int frameSize = SyncSafeNumber.DecodeNormal(tagData, currentPos, 4); currentPos += 4; var frameFlags = (ushort)((tagData[currentPos] << 0x08) + tagData[currentPos + 1]); currentPos += 2; var frameData = new byte[frameSize]; Array.Copy(tagData, currentPos, frameData, 0, frameSize); FrameHandler mapping = FrameHandlers[frameId]; if (mapping != null && mapping.Decoder != null) { Id3Frame frame = mapping.Decoder(frameData); tag.Frames.Add(frame); } currentPos += frameSize; } return(tag); }
internal override Id3Tag ReadTag(Stream stream, out object additionalData) { if (!HasTag(stream)) { additionalData = null; return(null); } Id3Tag tag = CreateTag(); stream.Seek(4, SeekOrigin.Begin); var headerBytes = new byte[6]; stream.Read(headerBytes, 0, 6); var headerContainer = new Id3V2Header(); additionalData = headerContainer; byte flags = headerBytes[1]; var header = new Id3V2StandardHeader { Revision = headerBytes[0], Unsyncronization = (flags & 0x80) > 0, ExtendedHeader = (flags & 0x40) > 0, Experimental = (flags & 0x20) > 0 }; headerContainer.Header = header; int tagSize = SyncSafeNumber.DecodeSafe(headerBytes, 2, 4); var tagData = new byte[tagSize]; stream.Read(tagData, 0, tagSize); var currentPos = 0; if (header.ExtendedHeader) { SyncSafeNumber.DecodeSafe(tagData, currentPos, 4); currentPos += 4; var extendedHeader = new Id3V2ExtendedHeader { PaddingSize = SyncSafeNumber.DecodeNormal(tagData, currentPos + 2, 4) }; if ((tagData[currentPos] & 0x80) > 0) { extendedHeader.Crc32 = SyncSafeNumber.DecodeNormal(tagData, currentPos + 6, 4); currentPos += 10; } else { currentPos += 6; } headerContainer.ExtendedHeader = extendedHeader; } while (currentPos < tagSize && tagData[currentPos] != 0x00) { string frameId = Encoding.ASCII.GetString(tagData, currentPos, 4); currentPos += 4; int frameSize = SyncSafeNumber.DecodeNormal(tagData, currentPos, 4); currentPos += 4; var frameFlags = (ushort)((tagData[currentPos] << 0x08) + tagData[currentPos + 1]); currentPos += 2; var frameData = new byte[frameSize]; Array.Copy(tagData, currentPos, frameData, 0, frameSize); FrameHandler mapping = FrameHandlers[frameId]; if (mapping != null) { Id3Frame frame = mapping.Decoder(frameData); tag.AddUntypedFrame(frame); } currentPos += frameSize; } return(tag); }