Beispiel #1
0
        /*
         * xx xx xx xx		Extended Header size, excluding itself; currently 6 or 10 bytes; not sync safe.
         * xx xx			Flags
         * xx xx xx xx		Size of padding; not sync safe
         * [xx xx xx xx]	4 bytes of CRC Data; not sync safe
         *
         */
        private static void EncodeID3v2_3ExtendedHeader(Stream s, ExtendedHeader extHeader, long paddingLen, long crc)
        {
            bool writeCRCData = ((extHeader.Flags & ExtendedHeaderFlags.CrcPresent) == ExtendedHeaderFlags.CrcPresent);
            int size = (writeCRCData ? 10 : 6);

            NumberConverter.WriteInt(size, s, 4, false);
            s.WriteByte((writeCRCData ? (byte)0x80 : (byte)0x00));
            s.WriteByte(0x00);
            NumberConverter.WriteInt(paddingLen, s, 4, false);
            if (writeCRCData) {
                NumberConverter.WriteInt(crc, s, 4, false);
                /* update crc checksum in extended header */
                extHeader.CrcChecksum = crc;
            }
        }
Beispiel #2
0
        /*
         * xx xx xx xx				Extended header size(min 6) as syncsafe int
         * xx						Number of flag bytes(currently 1)
         * xx						Flags
         * {sizeByte [flagdata]}	For every set bit in flag one entry
         *
         */
        private static void EncodeID3v2_4ExtendedHeader(Stream s, ExtendedHeader extHeader, long crc)
        {
            int size = 6;
            byte flagByte = 0;

            /* compute flag byte */
            if ((extHeader.Flags & ExtendedHeaderFlags.UpdateTag) == ExtendedHeaderFlags.UpdateTag) {
                flagByte |= 0x40;
                size += 1;
            }
            if ((extHeader.Flags & ExtendedHeaderFlags.CrcPresent) == ExtendedHeaderFlags.CrcPresent) {
                flagByte |= 0x20;
                size += 6;
            }
            if ((extHeader.Flags & ExtendedHeaderFlags.RestrictTag) == ExtendedHeaderFlags.RestrictTag) {
                flagByte |= 0x10;
                size += 2;
            }

            /* write Header */
            NumberConverter.WriteInt(size, s, 4, true);
            s.WriteByte(0x01);
            s.WriteByte(flagByte);

            /* write attached data */
            if ((extHeader.Flags & ExtendedHeaderFlags.UpdateTag) != 0) {
                s.WriteByte(0x00);
            }
            if ((extHeader.Flags & ExtendedHeaderFlags.CrcPresent) != 0) {
                s.WriteByte(0x05);
                NumberConverter.WriteInt(crc, s, 5, true);
                /* update crc checksum in extended header */
                extHeader.CrcChecksum = crc;
            }
            if ((extHeader.Flags & ExtendedHeaderFlags.RestrictTag) != 0) {
                byte restrictFlagByte = 0;

                restrictFlagByte |= (byte)extHeader.TagSizeRestriction;
                restrictFlagByte |= (byte)extHeader.TextEncodingRestriction;
                restrictFlagByte |= (byte)extHeader.TextFieldSizeRestriction;
                restrictFlagByte |= (byte)extHeader.TextFieldSizeRestriction;
                restrictFlagByte |= (byte)extHeader.ImageEncodingRestriction;
                restrictFlagByte |= (byte)extHeader.ImageSizeRestriction;

                s.WriteByte(0x01);
                s.WriteByte(restrictFlagByte);
            }
        }
Beispiel #3
0
        /*
         * xx xx xx xx				Extended header size(min 6) as syncsafe int
         * xx						Number of flag bytes(currently 1)
         * xx						Flags
         * {sizeByte [flagdata]}	For every set bit in flag one entry
         *
         */
        private static int DecodeID3v2_4ExtendedHeader(byte[] tagContent, ExtendedHeader extHeader)
        {
            int extHeaderSize, index;

            CheckLength(tagContent, 6);
            extHeaderSize = NumberConverter.ReadInt32(tagContent, 0, 4, true);
            if (extHeaderSize < 6) {
                throw new ID3ParseException("Size mismatch in extended header.");
            }
            if (tagContent[4] != 0x01) {
                throw new ID3ParseException("Flag byte count in extended header does not match.");
            }
            CheckLength(tagContent, extHeaderSize);

            /* parse extended header flags */
            extHeader.Flags = ExtendedHeaderFlags.None;
            index = 6;
            if ((tagContent[5] & 0x40) != 0) {
                extHeader.Flags |= ExtendedHeaderFlags.UpdateTag;
                if (index >= extHeaderSize || tagContent[index] != 0x00) {
                    throw new ID3ParseException("Error while parsing extended header flag data.");
                }
                index += 1;
            }
            if ((tagContent[5] & 0x20) != 0) {
                extHeader.Flags |= ExtendedHeaderFlags.CrcPresent;
                if (index + 5 >= extHeaderSize || tagContent[index] != 0x05) {
                    throw new ID3ParseException("Error while parsing extended header flag data.");
                }

                long savedCrc = NumberConverter.ReadInt64(tagContent, index + 1, 5, true);
                Crc32 crcCalculator = new Crc32();

                crcCalculator.UpdateCrc(tagContent, extHeaderSize, tagContent.Length - extHeaderSize);
                if (savedCrc != crcCalculator.Crc) {
                    throw new ID3CrcMismatchException(savedCrc, crcCalculator.Crc);
                }
                extHeader.CrcChecksum = savedCrc;

                index += 6;
            }
            if ((tagContent[5] & 0x10) != 0) {
                extHeader.Flags |= ExtendedHeaderFlags.RestrictTag;
                if (index + 1 >= extHeaderSize || tagContent[index] != 0x01) {
                    throw new ID3ParseException("Error while parsing extended header flag data.");
                }
                index += 1;
                extHeader.TagSizeRestriction = (TagSizeRestriction)(tagContent[index] & 0xC0);
                extHeader.TextEncodingRestriction = (TextEncodingRestriction)(tagContent[index] & 0x20);
                extHeader.TextFieldSizeRestriction = (TextFieldSizeRestriction)(tagContent[index] & 0x18);
                extHeader.ImageEncodingRestriction = (ImageEncodingRestriction)(tagContent[index] & 0x4);
                extHeader.ImageSizeRestriction = (ImageSizeRestriction)(tagContent[index] & 0x3);
                index += 1;
            }
            if ((tagContent[5] & 0x8F) != 0) {
                throw new ID3ParseException("Invalid entended header flag set.");
            }
            if (index != extHeaderSize) {
                throw new ID3ParseException("Size mismatch in extended header.");
            }

            return extHeaderSize;
        }
Beispiel #4
0
        public bool Equals(ExtendedHeader other)
        {
            if (other == null) {
                return false;
            }

            if (flags != other.flags) {
                return false;
            }
            if ((flags & ExtendedHeaderFlags.CrcPresent) == ExtendedHeaderFlags.CrcPresent && crcChecksum != other.crcChecksum) {
                return false;
            }
            if ((flags & ExtendedHeaderFlags.RestrictTag) == ExtendedHeaderFlags.RestrictTag) {
                if (textEncodingRestriction != other.textEncodingRestriction ||
                    tagSizeRestriction != other.tagSizeRestriction ||
                    textFieldSizeRestriction != other.textFieldSizeRestriction ||
                    imageEncodingRestriction != other.imageEncodingRestriction ||
                    imageSizeRestriction != other.imageSizeRestriction) {

                    return false;
                }
            }

            return true;
        }
Beispiel #5
0
        /*
         * xx xx xx xx		Extended Header size, excluding itself; currently 6 or 10 bytes; not sync safe.
         * xx xx			Flags
         * xx xx xx xx		Size of padding; not sync safe
         * [xx xx xx xx]	4 bytes of CRC Data; not sync safe
         *
         */
        private static int DecodeID3v2_3ExtendedHeader(byte[] tagContent, ExtendedHeader extHeader)
        {
            int extHeaderSize, paddingSize;

            CheckLength(tagContent, 10);
            extHeaderSize = NumberConverter.ReadInt32(tagContent, 0, 4, false);
            paddingSize = NumberConverter.ReadInt32(tagContent, 6, 4, false);

            if ((tagContent[4] & 0x7F) != 0 || tagContent[5] != 0x00) {
                throw new ID3ParseException("Unknown extended header flag set.");
            }

            if (tagContent[4] == 0x80) {
                extHeader.Flags = ExtendedHeaderFlags.CrcPresent;
                if (extHeaderSize != 10) {
                    throw new ID3ParseException("Invalid extended header size.");
                }
                CheckLength(tagContent, 14);

                long savedCrc = NumberConverter.ReadInt64(tagContent, 10, 4, false);
                int dataLength = tagContent.Length - 14 - paddingSize;
                Crc32 crcCalculator = new Crc32();

                if (dataLength < 0) {
                    throw new ID3ParseException("Padding size mismatch in extended header.");
                }
                crcCalculator.UpdateCrc(tagContent, 14, dataLength);
                if (savedCrc != crcCalculator.Crc) {
                    throw new ID3CrcMismatchException(savedCrc, crcCalculator.Crc);
                }
                extHeader.CrcChecksum = savedCrc;

            } else {
                extHeader.Flags = ExtendedHeaderFlags.None;
                if (extHeaderSize != 6) {
                    throw new ID3ParseException("Invalid extended header size.");
                }
            }

            return extHeaderSize;
        }