Esempio n. 1
0
        /*
         * ID3			Tag identifier
         * 04 00		2 bytes version
         * xx			Tag flags
         * xx xx xx xx	Tag size excluding header and footer as syncsafe int
         * [Extended header]
         * {Frames}
         * [Padding]
         * [Footer]
         */
        private static void EncodeID3v2_4Tag(Stream s, ID3v2Tag tag)
        {
            byte flagByte = 0;
            long paddingLen, size;

            const long TagHeaderSize = 10L;

            if ((tag.Flags & ID3v2TagFlags.Unsync) == ID3v2TagFlags.Unsync) {
                flagByte |= 0x80;
            }
            if (tag.ExtendedHeader != null) {
                flagByte |= 0x40;
            }
            if ((tag.Flags & ID3v2TagFlags.Experimental) == ID3v2TagFlags.Experimental) {
                flagByte |= 0x20;
            }
            if ((tag.Flags & ID3v2TagFlags.Footer) == ID3v2TagFlags.Footer) {
                flagByte |= 0x10;
            }

            StringEncoder.WriteLatin1String(s, "ID3", 3);
            s.WriteByte(0x04);
            s.WriteByte(0x00);
            s.WriteByte(flagByte);

            /* skip size */
            s.Position += 4;

            if (tag.ExtendedHeader != null) {
                byte[] frameData = GetFrameRawData(tag);
                long crc = -1L;

                if ((tag.ExtendedHeader.Flags & ExtendedHeaderFlags.CrcPresent) == ExtendedHeaderFlags.CrcPresent) {
                    /* CRC is calculated on frame data and padding */
                    Crc32 crcCalc = new Crc32();
                    crcCalc.UpdateCrc(frameData);
                    crcCalc.UpdateCrcWithZero(ComputePaddingSize(frameData.Length + TagHeaderSize, tag));
                    crc = crcCalc.Crc;
                }
                EncodeID3v2_4ExtendedHeader(s, tag.ExtendedHeader, crc);
                s.Write(frameData, 0, frameData.Length);

            } else {
                foreach (Frame f in tag.Frames) {
                    FrameEncoder.EncodeFrame(s, f, tag);
                }
            }

            paddingLen = ComputePaddingSize(s.Length, tag);
            s.SetLength(s.Length + paddingLen);
            size = s.Length - TagHeaderSize;

            if ((tag.Flags & ID3v2TagFlags.Footer) == ID3v2TagFlags.Footer) {
                s.Position = s.Length - 1L;
                StringEncoder.WriteLatin1String(s, "3DI", 3);
                s.WriteByte(0x04);
                s.WriteByte(0x00);
                s.WriteByte(flagByte);
                NumberConverter.WriteInt(size, s, 4, true);
            }

            s.Position = 6L;
            NumberConverter.WriteInt(size, s, 4, true);
        }