Example #1
0
        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);
        }
Example #2
0
        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);
        }