예제 #1
0
 public XingHeader(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (!data.StartsWith(FileIdentifier))
     {
         throw new CorruptFileException("Not a valid Xing header");
     }
     int startIndex = 8;
     if ((data[7] & 1) != 0)
     {
         this.frames = data.Mid(startIndex, 4).ToUInt();
         startIndex += 4;
     }
     else
     {
         this.frames = 0;
     }
     if ((data[7] & 2) != 0)
     {
         this.size = data.Mid(startIndex, 4).ToUInt();
         startIndex += 4;
     }
     else
     {
         this.size = 0;
     }
     this.present = true;
 }
예제 #2
0
 public static AviStream ParseStreamList (ByteVector data)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
    AviStream stream = null;
    int pos = 4;
    
    if (data.StartsWith ("strl"))
       while (pos + 8 < data.Count)
       {
          ByteVector id = data.Mid (pos, 4);
          int block_length = (int) data.Mid (pos + 4, 4).ToUInt (false);
          
          if (id == "strh" && stream == null)
          {
             AviStreamHeader stream_header = new AviStreamHeader (data, pos + 8);
             if (stream_header.Type == "vids")
                stream = new AviVideoStream (stream_header);
             else if (stream_header.Type == "auds")
                stream = new AviAudioStream (stream_header);
          }
          else if (stream != null)
             stream.ParseItem (id, data, pos + 8, block_length);
          
          pos += block_length + 8;
       }
    
    return stream;
 }
예제 #3
0
		//private void Read(ByteVector data, long stream_length, ReadStyle style)
		private void Read(ByteVector data, long streamLength)
		{
			if (data.StartsWith("MP+"))
				return;

			version = data[3] & 15;

			uint frames;

			if (version >= 7)
			{
				frames = data.Mid(4, 4).ToUInt(false);
				uint flags = data.Mid(8, 4).ToUInt(false);
				sampleRate = sfTable[(int)(((flags >> 17) & 1) * 2 + ((flags >> 16) & 1))];
				channels = 2;
			}
			else
			{
				uint headerData = data.Mid(0, 4).ToUInt(false);
				bitrate = (int)((headerData >> 23) & 0x01ff);
				version = (int)((headerData >> 11) & 0x03ff);
				sampleRate = 44100;
				channels = 2;
				if (version >= 5)
					frames = data.Mid(4, 4).ToUInt(false);
				else
					frames = data.Mid(4, 2).ToUInt(false);
			}

			uint samples = frames * 1152 - 576;
			duration = sampleRate > 0 ? TimeSpan.FromSeconds((double)samples / (double)sampleRate + 0.5) : TimeSpan.Zero;

			if (bitrate == 0)
				bitrate = (int)(duration > TimeSpan.Zero ? ((streamLength * 8L) / duration.TotalSeconds) / 1000 : 0);
		}		
예제 #4
0
		protected void Parse(ByteVector data)
		{
			if (data != null)
			{
				if (data.Count < Size)
					return;

				// The first eight buffer, data[0..7], are the File Identifier, "APETAGEX".

				// Read the version number
				version = data.Mid(8, 4).ToUInt(false);

				// Read the tag size
				tagSize = data.Mid(12, 4).ToUInt(false);

				// Read the item count
				itemCount = data.Mid(16, 4).ToUInt(false);

				// Read the flags

				uint flags = data.Mid(20, 4).ToUInt(false);

				headerPresent = (flags >> 31) == 1;
				footerPresent = (flags >> 30) != 1;
				isHeader = (flags >> 29) == 1;
			}
			else throw new ArgumentNullException("data");
		}
예제 #5
0
		private void Parse(ByteVector data)
		{
			// Check to see if a valid Xing header is available.

			if (!data.StartsWith("Xing"))
				return;

			// If the XingHeader doesn'type contain the number of frames and the total stream
			// info it'field invalid.

			if ((data[7] & 0x02) == 0)
			{
				TagLibDebugger.Debug("MPEG::XingHeader::parse() -- Xing header doesn't contain the total number of frames.");
				return;
			}

			if ((data[7] & 0x04) == 0)
			{
				TagLibDebugger.Debug("MPEG::XingHeader::parse() -- Xing header doesn't contain the total stream size.");
				return;
			}

			frames = data.Mid(8, 4).ToUInt();
			size = data.Mid(12, 4).ToUInt();

			valid = true;
		}
예제 #6
0
 public static AviStream ParseStreamList(ByteVector data)
 {
     int num2;
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (!data.StartsWith("strl"))
     {
         return null;
     }
     AviStream stream = null;
     for (int i = 4; (i + 8) < data.Count; i += num2 + 8)
     {
         ByteVector id = data.Mid(i, 4);
         num2 = (int) data.Mid(i + 4, 4).ToUInt(false);
         if ((id == "strh") && (stream == null))
         {
             AviStreamHeader header = new AviStreamHeader(data, i + 8);
             if (header.Type == "vids")
             {
                 stream = new AviVideoStream(header);
             }
             else if (header.Type == "auds")
             {
                 stream = new AviAudioStream(header);
             }
         }
         else if (stream != null)
         {
             stream.ParseItem(id, data, i + 8, num2);
         }
     }
     return stream;
 }
		private void ParseRelativeVolumeFields(ByteVector data)
		{
			int pos = data.Find(TextDelimiter(StringType.Latin1));
			if (pos < 0)
				return;

			identification = data.Mid(0, pos).ToString(StringType.Latin1);
			pos += 1;

			// Each channel is at least 4 buffer.

			while (pos <= data.Count - 4)
			{
				Id3v2ChannelType type = (Id3v2ChannelType)data[pos];
				pos += 1;

				SetVolumeAdjustmentIndex(data.Mid(pos, 2).ToShort(), type);
				pos += 2;

				int bytes = BitsToBytes(data[pos]);
				pos += 1;

				SetPeakVolumeIndex(ParsePeakVolume(data.Mid(pos, bytes)), type);
				pos += bytes;
			}
		}
		private void ParseCommentsFields(ByteVector data)
		{
			if (data.Count < 5)
			{
				TagLibDebugger.Debug("A comment frame must contain at least 5 bytes.");
				return;
			}

			textEncoding = (StringType)data[0];
			language = data.Mid(1, 3);

			int byte_align = textEncoding == StringType.Latin1 || textEncoding == StringType.UTF8 ? 1 : 2;

			ByteVectorCollection l = ByteVectorCollection.Split(data.Mid(4), TextDelimiter(textEncoding), byte_align, 2);

			if (l.Count == 2)
			{
				if (l[0].Data != null && l[0].Data.Count > 0)
					description = l[0].ToString(textEncoding);
				else description = string.Empty;
				
				if (l[1].Data != null && l[1].Data.Count > 0)
					text = l[1].ToString(textEncoding);
				else text = string.Empty;
			}
		}
 public StreamHeader(ByteVector data, long streamLength)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (!data.StartsWith(FileIdentifier))
     {
         throw new CorruptFileException("Data does not begin with identifier.");
     }
     if (data.Count < 0x38L)
     {
         throw new CorruptFileException("Insufficient data in stream header");
     }
     this.stream_length = streamLength;
     this.version = data[3] & 15;
     if (this.version >= 7)
     {
         this.frames = data.Mid(4, 4).ToUInt(false);
         uint num = data.Mid(8, 4).ToUInt(false);
         this.sample_rate = sftable[(((num >> 0x11) & 1) * 2) + ((num >> 0x10) & 1)];
         this.header_data = 0;
     }
     else
     {
         this.header_data = data.Mid(0, 4).ToUInt(false);
         this.version = ((int) (this.header_data >> 11)) & 0x3ff;
         this.sample_rate = 0xac44;
         this.frames = data.Mid(4, (this.version < 5) ? 2 : 4).ToUInt(false);
     }
 }
예제 #10
0
 public Picture(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (data.Count < 0x20)
     {
         throw new CorruptFileException("Data must be at least 32 bytes long");
     }
     int startIndex = 0;
     this.type = (PictureType) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     int count = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.mime_type = data.ToString(StringType.Latin1, startIndex, count);
     startIndex += count;
     int num3 = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.description = data.ToString(StringType.UTF8, startIndex, num3);
     startIndex += num3;
     this.width = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.height = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.color_depth = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.indexed_colors = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     int length = (int) data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.picture_data = data.Mid(startIndex, length);
 }
예제 #11
0
		public AsfGuid(ByteVector raw)
		{
			if (raw != null)
			{
				this.part1 = raw.Mid(0, 4).ToUInt(false);
				this.part2 = raw.Mid(4, 2).ToShort(false);
				this.part3 = raw.Mid(6, 2).ToShort(false);
				this.part4 = raw.Mid(8, 2).ToShort(true);
				this.part5 = raw.Mid(10, 6).ToLong(true);
			}
			else throw new ArgumentNullException("raw");
		}
예제 #12
0
 public StreamHeader (ByteVector data, long streamLength)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
    if (data.Count < 18)
       throw new CorruptFileException ("Not enough data in FLAC header.");
    
    this.stream_length = streamLength;
    this.flags = data.Mid (10, 4).ToUInt (true);
    low_length = data.Mid (14, 4).ToUInt (true);
 }
예제 #13
0
 protected void Parse (ByteVector data, byte version)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
    size = SynchData.ToUInt (data.Mid (0, 4));
 }
예제 #14
0
        public override bool ReadPacket(ByteVector packet, int index)
        {
            if (packet == null)
            {
                throw new ArgumentNullException("packet");
            }
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException("index", "index must be at least zero.");
            }
            int num = PacketType(packet);
            if ((num != 0x80) && (index == 0))
            {
                throw new CorruptFileException("Stream does not begin with theora header.");
            }
            if (this.comment_data == null)
            {
                switch (num)
                {
                    case 0x80:
                        this.header = new HeaderPacket(packet);
                        goto Label_009D;

                    case 0x81:
                        this.comment_data = packet.Mid(7);
                        goto Label_009D;
                }
                return true;
            }
        Label_009D:
            return (this.comment_data != null);
        }
		// We can make our own handler.
		public Mpeg4IsoHandlerBox(ByteVector handlerType, string name, Mpeg4Box parent) : base("hdlr", 0, parent)
		{
			if (handlerType != null)
				this.handlerType = handlerType.Mid(0, 4);
			
			this.name = name;
		}
예제 #16
0
      public Footer (ByteVector data)
      {
         if (data.Count < Size)
            throw new CorruptFileException ("Provided data is smaller than object size.");
         
         if (!data.StartsWith (FileIdentifier))
            throw new CorruptFileException ("Provided data does not start with File Identifier");
         
         major_version   = data [3];
         revision_number = data [4];
         flags           = (HeaderFlags) data [5];
         
         
         if (major_version == 2 && (flags & (HeaderFlags) 127) != 0)
            throw new CorruptFileException ("Invalid flags set on version 2 tag.");
         
         if (major_version == 3 && (flags & (HeaderFlags) 15) != 0)
            throw new CorruptFileException ("Invalid flags set on version 3 tag.");
         
         if (major_version == 4 && (flags & (HeaderFlags) 7) != 0)
            throw new CorruptFileException ("Invalid flags set on version 4 tag.");
         
         
         ByteVector size_data = data.Mid (6, 4);
         
         foreach (byte b in size_data)
            if (b >= 128)
               throw new CorruptFileException ("One of the bytes in the header was greater than the allowed 128.");

         tag_size = SynchData.ToUInt (size_data);
      }
		protected void Parse(ByteVector data)
		{
			if (data != null)
			{
				size = Id3v2SynchData.ToUInt(data.Mid(0, 4));
			}
			else throw new ArgumentNullException("data");
		}
 protected void Parse(ByteVector data, byte version)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     this.size = ((version != 3) ? 0 : 4) + SynchData.ToUInt(data.Mid(0, 4));
 }
예제 #19
0
 public VBRIHeader(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (!data.StartsWith(FileIdentifier))
     {
         throw new CorruptFileException("Not a valid VBRI header");
     }
     int startIndex = 10;
     this.size = data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.frames = data.Mid(startIndex, 4).ToUInt();
     startIndex += 4;
     this.present = true;
 }
예제 #20
0
 private void Parse(ByteVector data)
 {
     this.title = data.ToString(StringType.Latin1, 0, 0x20).Trim();
     this.artist = data.ToString(StringType.Latin1, 0x20, 0x1c).Trim();
     this.year = data.ToString(StringType.Latin1, 60, 4).Trim();
     this.comment = data.ToString(StringType.Latin1, 0x40, 0x30).Trim();
     this.genre = data.ToString(StringType.Latin1, 0x70, 3).Trim();
     this.extra_data = data.Mid(0x73, 6);
 }
예제 #21
0
 private void Parse(ByteVector data)
 {
     title      = data.ToString(StringType.Latin1, 0, 32).Trim();
     artist     = data.ToString(StringType.Latin1, 32, 28).Trim();
     year       = data.ToString(StringType.Latin1, 60, 4).Trim();
     comment    = data.ToString(StringType.Latin1, 64, 48).Trim();
     genre      = data.ToString(StringType.Latin1, 112, 3).Trim();
     extra_data = data.Mid(115, 6);
 }
        /// <summary>
        ///    Populates the current instance with the contents of the
        ///    raw ID3v2 frame.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the raw
        ///    extended header structure.
        /// </param>
        /// <param name="version">
        ///    A <see cref="byte" /> value indicating the ID3v2 version.
        /// </param>
        protected void Parse(ByteVector data, byte version)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            size = (version == 3 ? 4u : 0u) + SynchData.ToUInt(data.Mid(0, 4));
        }
예제 #23
0
        /// <summary>
        ///    Populates the values in the current instance by parsing
        ///    its field data in a specified version.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the
        ///    extracted field data.
        /// </param>
        /// <param name="version">
        ///    A <see cref="byte" /> indicating the ID3v2 version the
        ///    field data is encoded in.
        /// </param>
        protected override void ParseFields(ByteVector data,
                                            byte version)
        {
            if (data.Count < 6)
            {
                throw new CorruptFileException(
                          "Not enough bytes in field.");
            }

            encoding         = (StringType)data [0];
            language         = data.ToString(StringType.Latin1, 1, 3);
            timestamp_format = (TimestampFormat)data [4];
            lyrics_type      = (SynchedTextType)data [5];

            ByteVector delim = ByteVector.TextDelimiter(
                encoding);
            int delim_index = data.Find(delim, 6, delim.Count);

            if (delim_index < 0)
            {
                throw new CorruptFileException(
                          "Text delimiter expected.");
            }

            description = data.ToString(encoding, 6,
                                        delim_index - 6);

            int offset           = delim_index + delim.Count;
            List <SynchedText> l = new List <SynchedText> ();

            while (offset + delim.Count + 4 < data.Count)
            {
                delim_index = data.Find(delim, offset,
                                        delim.Count);

                if (delim_index < offset)
                {
                    throw new CorruptFileException(
                              "Text delimiter expected.");
                }

                string text = data.ToString(encoding, offset,
                                            delim_index - offset);
                offset = delim_index + delim.Count;

                if (offset + 4 > data.Count)
                {
                    break;
                }

                l.Add(new SynchedText(data.Mid(offset, 4)
                                      .ToUInt(), text));
                offset += 4;
            }

            this.text = l.ToArray();
        }
예제 #24
0
        public Picture(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Count < 32)
            {
                throw new CorruptFileException("Data must be at least 32 bytes long");
            }

            int pos = 0;

            _type = (PictureType)data.Mid(pos, 4).ToUInt();
            pos  += 4;

            int mimetype_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            _mimetype = data.ToString(StringType.Latin1, pos, mimetype_length);
            pos      += mimetype_length;

            int description_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            _description = data.ToString(StringType.UTF8, pos, description_length);
            pos         += description_length;

            _width = (int)data.Mid(pos, 4).ToUInt();
            pos   += 4;

            _height = (int)data.Mid(pos, 4).ToUInt();
            pos    += 4;

            _color_depth = (int)data.Mid(pos, 4).ToUInt();
            pos         += 4;

            _indexed_colors = (int)data.Mid(pos, 4).ToUInt();
            pos            += 4;

            int data_length = (int)data.Mid(pos, 4).ToUInt();

            pos += 4;

            _data = data.Mid(pos, data_length);
        }
예제 #25
0
        /// <summary>
        ///    Looks for a tag ending at a specified position and moves
        ///    the cursor to its start position.
        /// </summary>
        /// <param name="position">
        ///    A <see cref="long" /> value reference specifying at what
        ///    position the potential tag ends. If a tag is found,
        ///    this value will be updated to the position at which the
        ///    found tag starts.
        /// </param>
        /// <returns>
        ///    A <see cref="TagLib.TagTypes" /> value specifying the
        ///    type of tag found at the specified position, or <see
        ///    cref="TagTypes.None" /> if no tag was found.
        /// </returns>
        private TagTypes ReadTagInfo(ref long position)
        {
            if (position - read_size < 0)
            {
                return(TagTypes.None);
            }

            file.Seek(position - read_size);
            ByteVector data = file.ReadBlock(read_size);

            try {
                int offset;

                /*= (int) (data.Count - TagLib.Ape.Footer.Size);
                 *              if (data.ContainsAt (TagLib.Ape.Footer.FileIdentifier,
                 *                      offset)) {
                 *                      TagLib.Ape.Footer footer =
                 *                              new TagLib.Ape.Footer (
                 *                                      data.Mid (offset));
                 *
                 *                      // If the complete tag size is zero or
                 *                      // the tag is a header, this indicates
                 *                      // some sort of corruption.
                 *                      if (footer.CompleteTagSize == 0 ||
                 *                              (footer.Flags &
                 *                              TagLib.Ape.FooterFlags.IsHeader) != 0)
                 *                              return TagTypes.None;
                 *
                 *                      position -= footer.CompleteTagSize;
                 *                      return TagTypes.Ape;
                 *              }
                 */
                offset = (int)(data.Count - TagLib.Id3v2.Footer.Size);
                if (data.ContainsAt(TagLib.Id3v2.Footer.FileIdentifier,
                                    offset))
                {
                    TagLib.Id3v2.Footer footer =
                        new TagLib.Id3v2.Footer(
                            data.Mid(offset));

                    position -= footer.CompleteTagSize;
                    return(TagTypes.Id3v2);
                }

                /*
                 * if (data.StartsWith (
                 *      TagLib.Id3v1.Tag.FileIdentifier)) {
                 *      position -= TagLib.Id3v1.Tag.Size;
                 *      return TagTypes.Id3v1;
                 * }
                 */
            } catch (CorruptFileException) {
            }

            return(TagTypes.None);
        }
예제 #26
0
        private void ReadIHDRChunk(int data_length)
        {
            if (data_length != 13)
            {
                throw new CorruptFileException("IHDR chunk data length must be 13");
            }
            ByteVector data = ReadChunkData(data_length);

            CheckCRC(IHDR_CHUNK_TYPE, data, ReadCRC());
            uint width  = data.Mid(0, 4).ToUInt(true);
            uint height = data.Mid(4, 4).ToUInt(true);

            if (width > Int32.MaxValue || height > Int32.MaxValue)
            {
                throw new CorruptFileException("PNG limits width and heigth to 2^31-1");
            }
            this.width  = (int)width;
            this.height = (int)height;
        }
예제 #27
0
        public static bool Find(out AudioHeader header, TagLib.File file, long position, int length)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }
            long end = position + length;

            header = AudioHeader.Unknown;
            file.Seek(position);
            ByteVector buffer = file.ReadBlock(3);

            if (buffer.Count < 3)
            {
                return(false);
            }
            do
            {
                file.Seek(position + 3);
                buffer = buffer.Mid(buffer.Count - 3);
                buffer.Add(file.ReadBlock((int)File.BufferSize));
                for (int i = 0; i < buffer.Count - 3 && (length < 0 || position + i < end); i++)
                {
                    if (buffer[i] == 0xFF && buffer[i + 1] > 0xE0)
                    {
                        ByteVector data = buffer.Mid(i, 4);
                        if (GetHeaderError(data) == null)
                        {
                            try
                            {
                                header = new AudioHeader(data, file, position + i);
                                return(true);
                            }
                            catch (CorruptFileException)
                            {
                            }
                        }
                    }
                }
                position += File.BufferSize;
            }while(buffer.Count > 3 && (length < 0 || position < end));
            return(false);
        }
예제 #28
0
 public StreamHeader(ByteVector data, long streamLength)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (!data.StartsWith(FileIdentifier))
     {
         throw new CorruptFileException("Data does not begin with identifier.");
     }
     if (data.Count < Size)
     {
         throw new CorruptFileException("Insufficient data in stream header");
     }
     stream_length = streamLength;
     version       = data.Mid(8, 2).ToUShort(false);
     flags         = data.Mid(24, 4).ToUInt(false);
     samples       = data.Mid(12, 4).ToUInt(false);
 }
예제 #29
0
 public Footer(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (data.Count < Size)
     {
         throw new CorruptFileException("Provided data is smaller than object size.");
     }
     if (!data.StartsWith(FileIdentifier))
     {
         throw new CorruptFileException("Provided data does not start with File Identifier");
     }
     version    = data.Mid(8, 4).ToUInt(false);
     tag_size   = data.Mid(12, 4).ToUInt(false);
     item_count = data.Mid(16, 4).ToUInt(false);
     flags      = (FooterFlags)data.Mid(20, 4).ToUInt(false);
 }
예제 #30
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="StreamHeader" /> by reading a raw stream header
        ///    structure and using the stream length.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the raw
        ///    stream header.
        /// </param>
        /// <param name="streamLength">
        ///    A <see cref="long" /> value containing the length of the
        ///    stream.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 18 bytes.
        /// </exception>
        public StreamHeader(ByteVector data, long streamLength)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Count < 18)
            {
                throw new CorruptFileException(
                          "Not enough data in FLAC header.");
            }

            stream_length = streamLength;
            flags         = data.Mid(10, 4)
                            .ToUInt(true);
            low_length = data.Mid(14, 4)
                         .ToUInt(true);
        }
예제 #31
0
        protected ByteVector FieldData(ByteVector frameData, int offset, byte version)
        {
            if (frameData == null)
            {
                throw new ArgumentNullException("frameData");
            }
            int data_offset = offset + (int)FrameHeader.Size(version);
            int data_length = (int)Size;

            if ((Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator)) != 0)
            {
                data_offset += 4;
                data_length -= 4;
            }
            if ((Flags & FrameFlags.GroupingIdentity) != 0)
            {
                if (frameData.Count >= data_offset)
                {
                    throw new TagLib.CorruptFileException("Frame data incomplete.");
                }
                group_id = frameData[data_offset++];
                data_length--;
            }
            if ((Flags & FrameFlags.Encryption) != 0)
            {
                if (frameData.Count >= data_offset)
                {
                    throw new TagLib.CorruptFileException("Frame data incomplete.");
                }
                encryption_id = frameData[data_offset++];
                data_length--;
            }
            data_length = Math.Min(data_length, frameData.Count - data_offset);
            if (data_length < 0)
            {
                throw new CorruptFileException("Frame size less than zero.");
            }
            ByteVector data = frameData.Mid(data_offset, data_length);

            if ((Flags & FrameFlags.Unsynchronisation) != 0)
            {
                int before_length = data.Count;
                SynchData.ResynchByteVector(data);
                data_length -= (data.Count - before_length);
            }
            if ((Flags & FrameFlags.Encryption) != 0)
            {
                throw new NotImplementedException();
            }
            if ((Flags & FrameFlags.Compression) != 0)
            {
                throw new NotImplementedException();
            }
            return(data);
        }
예제 #32
0
        /// <summary>
        ///    Parses a raw AVI stream list and returns the stream
        ///    information.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing raw stream
        ///    list.
        /// </param>
        /// <returns>
        ///    A <see cref="AviStream" /> object containing stream
        ///    information.
        /// </returns>
        public static AviStream ParseStreamList(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (!data.StartsWith("strl"))
            {
                return(null);
            }

            AviStream stream = null;
            int       pos    = 4;

            while (pos + 8 < data.Count)
            {
                ByteVector id           = data.Mid(pos, 4);
                int        block_length = (int)data.Mid(pos + 4, 4).ToUInt(false);

                if (id == "strh" && stream == null)
                {
                    var stream_header = new AviStreamHeader(data, pos + 8);
                    if (stream_header.Type == "vids")
                    {
                        stream = new AviVideoStream(stream_header);
                    }
                    else if (stream_header.Type == "auds")
                    {
                        stream = new AviAudioStream(stream_header);
                    }
                }
                else if (stream != null)
                {
                    stream.ParseItem(id, data, pos + 8, block_length);
                }

                pos += block_length + 8;
            }

            return(stream);
        }
예제 #33
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="VideoHeader" /> by reading it from a specified
        ///    location in a specified file.
        /// </summary>
        /// <param name="file">
        ///    A <see cref="TagLib.File" /> object to read from.
        /// </param>
        /// <param name="position">
        ///    A <see cref="long" /> value indicating the position in
        ///    <paramref name="file" /> at which the header begins.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="file" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    Insufficient data could be read for the header.
        /// </exception>
        public VideoHeader(TagLib.File file, long position)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            file.Seek(position);
            ByteVector data = file.ReadBlock(7);

            if (data.Count < 7)
            {
                throw new CorruptFileException("Insufficient data in header.");
            }

            VideoWidth       = data.Mid(0, 2).ToUShort() >> 4;
            VideoHeight      = data.Mid(1, 2).ToUShort() & 0x0FFF;
            frame_rate_index = data[3] & 0x0F;
            VideoBitrate     = (int)((data.Mid(4, 3).ToUInt() >> 6) & 0x3FFFF);
        }
예제 #34
0
 public WaveFormatEx(ByteVector data, int offset)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (offset < 0)
     {
         throw new ArgumentOutOfRangeException("offset");
     }
     if ((offset + 0x10) > data.Count)
     {
         throw new CorruptFileException("Expected 16 bytes.");
     }
     this.format_tag = data.Mid(offset, 2).ToUShort(false);
     this.channels = data.Mid(offset + 2, 2).ToUShort(false);
     this.samples_per_second = data.Mid(offset + 4, 4).ToUInt(false);
     this.average_bytes_per_second = data.Mid(offset + 8, 4).ToUInt(false);
     this.bits_per_sample = data.Mid(offset + 14, 2).ToUShort(false);
 }
예제 #35
0
 public WaveFormatEx(ByteVector data, int offset)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (offset < 0)
     {
         throw new ArgumentOutOfRangeException("offset");
     }
     if (offset + 16 > data.Count)
     {
         throw new CorruptFileException("Expected 16 bytes.");
     }
     format_tag               = data.Mid(offset, 2).ToUShort(false);
     channels                 = data.Mid(offset + 2, 2).ToUShort(false);
     samples_per_second       = data.Mid(offset + 4, 4).ToUInt(false);
     average_bytes_per_second = data.Mid(offset + 8, 4).ToUInt(false);
     bits_per_sample          = data.Mid(offset + 14, 2).ToUShort(false);
 }
예제 #36
0
 public BlockHeader (ByteVector data)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
    if (data.Count < Size)
       throw new CorruptFileException ("Not enough data in Flac header.");
    _block_type    = (BlockType) (data[0] & 0x7f);
    _is_last_block = (data[0] & 0x80) != 0;
    _block_size    = data.Mid (1,3).ToUInt ();
 }
예제 #37
0
        /// <summary>
        ///    Performs the actual parsing of the raw data.
        /// </summary>
        /// <remarks>
        ///    Because of the high parsing cost and relatively low usage
        ///    of the class, <see cref="ParseFields" /> only stores the
        ///    field data so it can be parsed on demand. Whenever a
        ///    property or method is called which requires the data,
        ///    this method is called, and only on the first call does it
        ///    actually parse the data.
        /// </remarks>
        protected void ParseRawData()
        {
            if (raw_data == null)
            {
                return;
            }

            ByteVector data = raw_data;

            raw_data = null;

            List <string> field_list = new List <string>();

            ByteVector delim = ByteVector.TextDelimiter(encoding);

            if (FrameId != FrameType.WXXX)
            {
                field_list.AddRange(data.ToStrings(StringType.Latin1, 0));
            }
            else if (data.Count > 1 && !data.Mid(0,
                                                 delim.Count).Equals(delim))
            {
                string value = data.ToString(StringType.Latin1, 1,
                                             data.Count - 1);

                // Do a fast removal of end bytes.
                if (value.Length > 1 &&
                    value[value.Length - 1] == 0)
                {
                    for (int i = value.Length - 1; i >= 0; i--)
                    {
                        if (value[i] != 0)
                        {
                            value = value.Substring(0, i + 1);
                            break;
                        }
                    }
                }

                field_list.Add(value);
            }

            // Bad tags may have one or more nul characters at the
            // end of a string, resulting in empty strings at the
            // end of the FieldList. Strip them off.
            while (field_list.Count != 0 &&
                   string.IsNullOrEmpty(field_list[
                                            field_list.Count - 1]))
            {
                field_list.RemoveAt(field_list.Count - 1);
            }

            text_fields = field_list.ToArray();
        }
예제 #38
0
        protected void Parse(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            int pos           = 0;
            int vendor_length = (int)data.Mid(pos, 4).ToUInt(false);

            pos      += 4;
            vendor_id = data.ToString(StringType.UTF8, pos, vendor_length);
            pos      += vendor_length;
            int comment_fields = (int)data.Mid(pos, 4).ToUInt(false);

            pos += 4;
            for (int i = 0; i < comment_fields; i++)
            {
                int comment_length = (int)data.Mid(pos, 4).ToUInt(false);
                pos += 4;
                string comment = data.ToString(StringType.UTF8, pos, comment_length);
                pos += comment_length;
                int comment_separator_position = comment.IndexOf('=');
                if (comment_separator_position < 0)
                {
                    continue;
                }
                string   key   = comment.Substring(0, comment_separator_position).ToUpper(CultureInfo.InvariantCulture);
                string   value = comment.Substring(comment_separator_position + 1);
                string[] values;
                if (field_list.TryGetValue(key, out values))
                {
                    Array.Resize <string>(ref values, values.Length + 1);
                    values[values.Length - 1] = value;
                    field_list[key]           = values;
                }
                else
                {
                    SetField(key, value);
                }
            }
        }
예제 #39
0
        private void ReadiTXtChunk(int data_length)
        {
            long       position = Tell;
            ByteVector data     = ReadChunkData(data_length);

            CheckCRC(iTXt_CHUNK_TYPE, data, ReadCRC());
            if (data.StartsWith(XMP_CHUNK_HEADER))
            {
                ImageTag.AddTag(new XmpTag(data.Mid(XMP_CHUNK_HEADER.Length).ToString(StringType.UTF8), this));
                AddMetadataBlock(position - 8, data_length + 8 + 4);
                return;
            }
            int    terminator_index;
            string keyword = ReadKeyword(data, 0, out terminator_index);

            if (terminator_index + 2 >= data_length)
            {
                throw new CorruptFileException("Compression Flag and Compression Method byte expected");
            }
            byte       compression_flag   = data[terminator_index + 1];
            byte       compression_method = data[terminator_index + 2];
            ByteVector txt_data           = data.Mid(terminator_index + 1);

            if (compression_flag != 0x00)
            {
                txt_data = Decompress(compression_method, txt_data);
                if (txt_data == null)
                {
                    return;
                }
            }
            string value   = txt_data.ToString();
            PngTag png_tag = GetTag(TagTypes.Png, true)
                             as PngTag;

            if (png_tag.GetKeyword(keyword) == null)
            {
                png_tag.SetKeyword(keyword, value);
            }
            AddMetadataBlock(position - 8, data_length + 8 + 4);
        }
예제 #40
0
        /// <summary>
        ///     Constructs and initializes a new instance of
        ///     <see
        ///         cref="AviStreamHeader" />
        ///     by reading the raw structure
        ///     from a specified position in a <see cref="ByteVector" />
        ///     object.
        /// </summary>
        /// <param name="data">
        ///     A <see cref="ByteVector" /> object containing the raw
        ///     data structure.
        /// </param>
        /// <param name="offset">
        ///     A <see cref="int" /> value specifying the index in
        ///     <paramref name="data" /> at which the structure begins.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     <paramref name="offset" /> is less than zero.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///     <paramref name="data" /> contains less than 40 bytes at
        ///     <paramref name="offset" />.
        /// </exception>
        public AviHeader(ByteVector data, int offset)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(offset));
            }

            if (offset + 40 > data.Count)
            {
                throw new CorruptFileException(
                          "Expected 40 bytes.");
            }

            MicrosecondsPerFrame = data.Mid(offset, 4)
                                   .ToUInt(false);

            MaxBytesPerSecond = data.Mid(offset + 4, 4)
                                .ToUInt(false);

            Flags = data.Mid(offset + 12, 4)
                    .ToUInt(false);

            TotalFrames = data.Mid(offset + 16, 4)
                          .ToUInt(false);

            InitialFrames = data.Mid(offset + 20, 4)
                            .ToUInt(false);

            Streams = data.Mid(offset + 24, 4)
                      .ToUInt(false);

            SuggestedBufferSize = data.Mid(offset + 28, 4)
                                  .ToUInt(false);

            Width = data.Mid(offset + 32, 4)
                    .ToUInt(false);

            Height = data.Mid(offset + 36, 4)
                     .ToUInt(false);
        }
예제 #41
0
        public AviHeader(ByteVector data, int offset)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            microseconds_per_frame = data.Mid(offset, 4).ToUInt(false);
            max_bytes_per_second   = data.Mid(offset + 4, 4).ToUInt(false);
            flags                 = data.Mid(offset + 12, 4).ToUInt(false);
            total_frames          = data.Mid(offset + 16, 4).ToUInt(false);
            initial_frames        = data.Mid(offset + 20, 4).ToUInt(false);
            streams               = data.Mid(offset + 24, 4).ToUInt(false);
            suggested_buffer_size = data.Mid(offset + 28, 4).ToUInt(false);
            width                 = data.Mid(offset + 32, 4).ToUInt(false);
            height                = data.Mid(offset + 36, 4).ToUInt(false);
        }
 protected override void ParseFields(ByteVector data, byte version)
 {
     ByteVector pattern = ByteVector.TextDelimiter(StringType.Latin1);
     int count = data.Find(pattern);
     if (count < 0)
     {
         throw new CorruptFileException("Popularimeter frame does not contain a text delimiter");
     }
     this.user = data.ToString(StringType.Latin1, 0, count);
     this.rating = data[count + 1];
     this.play_count = data.Mid(count + 2).ToULong();
 }
예제 #43
0
 protected ByteVector FieldData(ByteVector frameData, int offset, byte version)
 {
     if (frameData == null)
     {
         throw new ArgumentNullException("frameData");
     }
     int startIndex = offset + ((int) FrameHeader.Size(version));
     int size = (int) this.Size;
     if (((ushort) (this.Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator))) != 0)
     {
         startIndex += 4;
         size -= 4;
     }
     if (((ushort) (this.Flags & FrameFlags.GroupingIdentity)) != 0)
     {
         if (frameData.Count >= startIndex)
         {
             throw new CorruptFileException("Frame data incomplete.");
         }
         this.group_id = frameData[startIndex++];
         size--;
     }
     if (((ushort) (this.Flags & FrameFlags.Encryption)) != 0)
     {
         if (frameData.Count >= startIndex)
         {
             throw new CorruptFileException("Frame data incomplete.");
         }
         this.encryption_id = frameData[startIndex++];
         size--;
     }
     size = Math.Min(size, frameData.Count - startIndex);
     if (size < 0)
     {
         throw new CorruptFileException("Frame size less than zero.");
     }
     ByteVector data = frameData.Mid(startIndex, size);
     if (((ushort) (this.Flags & FrameFlags.Unsynchronisation)) != 0)
     {
         int count = data.Count;
         SynchData.ResynchByteVector(data);
         size -= data.Count - count;
     }
     if (((ushort) (this.Flags & FrameFlags.Encryption)) != 0)
     {
         throw new NotImplementedException();
     }
     if (((ushort) (this.Flags & FrameFlags.Compression)) != 0)
     {
         throw new NotImplementedException();
     }
     return data;
 }
예제 #44
0
            public HeaderPacket(ByteVector data)
            {
                int pos = 7;

                vorbis_version = data.Mid(pos, 4).ToUInt(false);

                pos     += 4;
                channels = data [pos];

                pos        += 1;
                sample_rate = data.Mid(pos, 4).ToUInt(false);

                pos            += 4;
                bitrate_maximum = data.Mid(pos, 4).ToUInt(false);

                pos            += 4;
                bitrate_nominal = data.Mid(pos, 4).ToUInt(false);

                pos            += 4;
                bitrate_minimum = data.Mid(pos, 4).ToUInt(false);
            }
예제 #45
0
            public HeaderPacket(ByteVector data)
            {
                major_version    = data [7];
                minor_version    = data [8];
                revision_version = data [9];
                // width = data.Mid (10, 2).ToShort () << 4;
                // height = data.Mid (12, 2).ToShort () << 4;
                width  = (int)data.Mid(14, 3).ToUInt();                   // Frame Width.
                height = (int)data.Mid(17, 3).ToUInt();                   // Frame Height.
                // Offset X.
                // Offset Y.
                fps_numerator   = (int)data.Mid(22, 4).ToUInt();
                fps_denominator = (int)data.Mid(26, 4).ToUInt();
                // Aspect Numerator.
                // Aspect Denominator.
                // Colorspace.
                // Target bitrate.
                ushort last_bits = data.Mid(40, 2).ToUShort();

                keyframe_granule_shift = (last_bits >> 5) & 0x1F;
            }
예제 #46
0
        private TagTypes ReadTagInfo(ref long position)
        {
            if (position - read_size < 0)
            {
                return(TagTypes.None);
            }
            file.Seek(position - read_size);
            ByteVector data = file.ReadBlock(read_size);

            try
            {
                int offset = (int)(data.Count - TagLib.Ape.Footer.Size);
                if (data.ContainsAt(TagLib.Ape.Footer.FileIdentifier, offset))
                {
                    TagLib.Ape.Footer footer = new TagLib.Ape.Footer(data.Mid(offset));
                    if (footer.CompleteTagSize == 0 || (footer.Flags & TagLib.Ape.FooterFlags.IsHeader) != 0)
                    {
                        return(TagTypes.None);
                    }
                    position -= footer.CompleteTagSize;
                    return(TagTypes.Ape);
                }
                offset = (int)(data.Count - TagLib.Id3v2.Footer.Size);
                if (data.ContainsAt(TagLib.Id3v2.Footer.FileIdentifier, offset))
                {
                    TagLib.Id3v2.Footer footer = new TagLib.Id3v2.Footer(data.Mid(offset));
                    position -= footer.CompleteTagSize;
                    return(TagTypes.Id3v2);
                }
                if (data.StartsWith(TagLib.Id3v1.Tag.FileIdentifier))
                {
                    position -= TagLib.Id3v1.Tag.Size;
                    return(TagTypes.Id3v1);
                }
            }
            catch (CorruptFileException)
            {
            }
            return(TagTypes.None);
        }
예제 #47
0
        /// <summary>
        ///    Populates the current instance by parsing the contents of
        ///    a raw ID3v1 tag.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the
        ///    starting with an ID3v1 tag.
        /// </param>
        private void Parse(ByteVector data)
        {
            title  = string_handler.Parse(data.Mid(3, 30));
            artist = string_handler.Parse(data.Mid(33, 30));
            album  = string_handler.Parse(data.Mid(63, 30));
            year   = string_handler.Parse(data.Mid(93, 4));

            // Check for ID3v1.1 -- Note that ID3v1 *does not*
            // support "track zero" -- this is not a bug in TagLib.
            // Since a zeroed byte is what we would expect to
            // indicate the end of a C-String, specifically the
            // comment string, a value of zero must be assumed to be
            // just that.

            if (data [125] == 0 && data [126] != 0)
            {
                // ID3v1.1 detected
                comment = string_handler.Parse(data.Mid(97, 28));
                track   = data [126];
            }
            else
            {
                comment = string_handler.Parse(data.Mid(97, 30));
            }

            genre = data [127];
        }
예제 #48
0
        /// <summary>
        ///    Populates the values in the current instance by parsing
        ///    its field data in a specified version.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the
        ///    extracted field data.
        /// </param>
        /// <param name="version">
        ///    A <see cref="byte" /> indicating the ID3v2 version the
        ///    field data is encoded in.
        /// </param>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> contains less than 5 bytes.
        /// </exception>
        protected override void ParseFields(ByteVector data,
                                            byte version)
        {
            int pos = data.Find(ByteVector.TextDelimiter(
                                    StringType.Latin1));

            if (pos < 0)
            {
                return;
            }

            identification = data.ToString(StringType.Latin1, 0,
                                           pos++);

            // Each channel is at least 4 bytes.

            while (pos <= data.Count - 4)
            {
                int type = data[pos++];

                unchecked
                {
                    channels[type].VolumeAdjustmentIndex =
                        (short)data.Mid(pos,
                                        2).ToUShort();
                }
                pos += 2;

                int bytes = BitsToBytes(data[pos++]);

                if (data.Count < pos + bytes)
                {
                    break;
                }

                channels[type].PeakVolumeIndex = data.Mid(pos,
                                                          bytes).ToULong();
                pos += bytes;
            }
        }
예제 #49
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="XingHeader" /> by reading its raw contents.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the raw
        ///    Xing header.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> does not start with <see
        ///    cref="FileIdentifier" />.
        /// </exception>
        public XingHeader(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            // Check to see if a valid Xing header is available.
            if (!data.StartsWith(FileIdentifier))
            {
                throw new CorruptFileException(
                          "Not a valid Xing header");
            }

            var position = 8;

            if ((data[7] & 0x01) != 0)
            {
                TotalFrames = data.Mid(position, 4)
                              .ToUInt();
                position += 4;
            }
            else
            {
                TotalFrames = 0;
            }

            if ((data[7] & 0x02) != 0)
            {
                TotalSize = data.Mid(position, 4)
                            .ToUInt();
                position += 4;
            }
            else
            {
                TotalSize = 0;
            }

            Present = true;
        }
예제 #50
0
        /// <summary>
        ///    Constructs and initializes a new instance of <see
        ///    cref="Header" /> by reading it from raw header data.
        /// </summary>
        /// <param name="data">
        ///    A <see cref="ByteVector" /> object containing the raw
        ///    data to build the new instance from.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///    <paramref name="data" /> is <see langword="null" />.
        /// </exception>
        /// <exception cref="CorruptFileException">
        ///    <paramref name="data" /> is smaller than <see
        ///    cref="Size" />, does not begin with <see
        ///    cref="FileIdentifier" />, contains invalid flag data,
        ///    or contains invalid size data.
        /// </exception>
        public Header(ByteVector data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Count < Size)
            {
                throw new CorruptFileException(
                          "Provided data is smaller than object size.");
            }

            if (!data.StartsWith(FileIdentifier))
            {
                throw new CorruptFileException(
                          "Provided data does not start with the file identifier");
            }

            major_version   = data [3];
            revision_number = data [4];
            flags           = (HeaderFlags)data [5];

            if (major_version == 2 && ((int)flags & 127) != 0)
            {
                throw new CorruptFileException(
                          "Invalid flags set on version 2 tag.");
            }

            if (major_version == 3 && ((int)flags & 15) != 0)
            {
                throw new CorruptFileException(
                          "Invalid flags set on version 3 tag.");
            }

            if (major_version == 4 && ((int)flags & 7) != 0)
            {
                throw new CorruptFileException(
                          "Invalid flags set on version 4 tag.");
            }

            for (int i = 6; i < 10; i++)
            {
                if (data [i] >= 128)
                {
                    throw new CorruptFileException(
                              "One of the bytes in the header was greater than the allowed 128.");
                }
            }

            tag_size = SynchData.ToUInt(data.Mid(6, 4));
        }
예제 #51
0
        private uint ReadIFD(long base_offset, uint offset, uint max_offset)
        {
            long length = 0;

            try
            {
                length = file.Length;
            }
            catch (Exception)
            {
                length = 1073741824L * 4;
            }
            if (base_offset + offset > length)
            {
                file.MarkAsCorrupt("Invalid IFD offset");
                return(0);
            }
            var directory = new IFDDirectory();

            file.Seek(base_offset + offset, SeekOrigin.Begin);
            ushort entry_count = ReadUShort();

            if (file.Tell + 12 * entry_count > base_offset + max_offset)
            {
                file.MarkAsCorrupt("Size of entries exceeds possible data size");
                return(0);
            }
            ByteVector entry_datas = file.ReadBlock(12 * entry_count);
            uint       next_offset = ReadUInt();

            for (int i = 0; i < entry_count; i++)
            {
                ByteVector entry_data  = entry_datas.Mid(i * 12, 12);
                ushort     entry_tag   = entry_data.Mid(0, 2).ToUShort(is_bigendian);
                ushort     type        = entry_data.Mid(2, 2).ToUShort(is_bigendian);
                uint       value_count = entry_data.Mid(4, 4).ToUInt(is_bigendian);
                ByteVector offset_data = entry_data.Mid(8, 4);
                IFDEntry   entry       = CreateIFDEntry(entry_tag, type, value_count, base_offset, offset_data, max_offset);
                if (entry == null)
                {
                    continue;
                }
                if (directory.ContainsKey(entry.Tag))
                {
                    directory.Remove(entry.Tag);
                }
                directory.Add(entry.Tag, entry);
            }
            FixupDirectory(base_offset, directory);
            structure.directories.Add(directory);
            return(next_offset);
        }
예제 #52
0
        /// <summary>
        ///    Reads and validates the TIFF header at the current position.
        /// </summary>
        /// <returns>
        ///    A <see cref="System.UInt32"/> with the offset value to the first
        ///    IFD contained in the file.
        /// </returns>
        /// <remarks>
        ///    This method should only be called, when the current read position is
        ///    the beginning of the file.
        /// </remarks>
        protected uint ReadHeader()
        {
            // TIFF header:
            //
            // 2 bytes         Indicating the endianess (II or MM)
            // 2 bytes         Tiff Magic word (usually 42)
            // 4 bytes         Offset to first IFD

            ByteVector header = ReadBlock(8);

            if (header.Count != 8)
            {
                throw new CorruptFileException("Unexpected end of header");
            }

            string order = header.Mid(0, 2).ToString();

            if (order == "II")
            {
                IsBigEndian = false;
            }
            else if (order == "MM")
            {
                IsBigEndian = true;
            }
            else
            {
                throw new CorruptFileException("Unknown Byte Order");
            }

            if (header.Mid(2, 2).ToUShort(IsBigEndian) != Magic)
            {
                throw new CorruptFileException(String.Format("TIFF Magic ({0}) expected", Magic));
            }

            uint first_ifd_offset = header.Mid(4, 4).ToUInt(IsBigEndian);

            return(first_ifd_offset);
        }
예제 #53
0
 private string ReadTerminatedString(ByteVector data, int start_index, out int terminator_index)
 {
     if (start_index >= data.Count)
     {
         throw new CorruptFileException("Unexpected End of Data");
     }
     terminator_index = data.Find("\0", start_index);
     if (terminator_index < 0)
     {
         throw new CorruptFileException("Cannot find string terminator");
     }
     return(data.Mid(start_index, terminator_index - start_index).ToString());
 }
예제 #54
0
            public HeaderPacket(ByteVector data)
            {
                opus_version  = data[8];
                channel_count = data[9];
                pre_skip      = data.Mid(10, 2)
                                .ToUInt(false);

                input_sample_rate = data.Mid(12, 4)
                                    .ToUInt(false);

                output_gain = data.Mid(16, 2)
                              .ToUInt(false);

                channel_map = data[18];

                if (channel_map == 0)
                {
                    stream_count             = 1;
                    two_channel_stream_count = channel_count - 1;

                    channel_mappings    = new uint[channel_count];
                    channel_mappings[0] = 0;
                    if (channel_count == 2)
                    {
                        channel_mappings[1] = 1;
                    }
                }
                else
                {
                    stream_count             = data[19];
                    two_channel_stream_count = data[20];

                    channel_mappings = new uint[channel_count];
                    for (var i = 0; i < channel_count; i++)
                    {
                        channel_mappings[i] = data[21 + i];
                    }
                }
            }
 public IsoHandlerBox(ByteVector handlerType, string name) : base("hdlr", 0, 0)
 {
     if (handlerType == null)
     {
         throw new ArgumentNullException("handlerType");
     }
     if (handlerType.Count < 4)
     {
         throw new ArgumentException("The handler type must be four bytes long.", "handlerType");
     }
     this.handler_type = handlerType.Mid(0, 4);
     this.name = name;
 }
예제 #56
0
 public BlockHeader(ByteVector data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     if (data.Count < 4L)
     {
         throw new CorruptFileException("Not enough data in Flac header.");
     }
     this.block_type = ((TagLib.Flac.BlockType) data[0]) & ((TagLib.Flac.BlockType) 0x7f);
     this.is_last_block = (data[0] & 0x80) != 0;
     this.block_size = data.Mid(1, 3).ToUInt();
 }
예제 #57
0
 public Picture (ByteVector data)
 {
    if (data == null)
       throw new ArgumentNullException ("data");
    
    if (data.Count < 32)
       throw new CorruptFileException ("Data must be at least 32 bytes long");
    
    int pos = 0;
    _type = (PictureType) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    int mimetype_length = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _mimetype = data.ToString (StringType.Latin1, pos, mimetype_length);
    pos += mimetype_length;
    
    int description_length = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _description = data.ToString (StringType.UTF8, pos, description_length);
    pos += description_length;
    
    _width = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _height = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _color_depth = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _indexed_colors = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    int data_length = (int) data.Mid (pos, 4).ToUInt ();
    pos += 4;
    
    _data = data.Mid (pos, data_length);
 }
예제 #58
0
		protected void Parse(ByteVector data)
		{
			if (data.Count < Size)
				return;

			// do some sanity checking -- even in ID3v2.3.0 and less the tag size is a
			// synch-safe integer, so all buffer must be less than 128.  If this is not
			// true then this is an invalid tag.

			// note that we're doing things a little out of order here -- the size is
			// later in the bytestream than the version

			ByteVector sizeData = data.Mid(6, 4);

			if (sizeData.Count != 4)
			{
				tagSize = 0;
				TagLibDebugger.Debug("ID3v2.Header.Parse () - The tag size as read was 0 bytes!");
				return;
			}

			foreach (byte b in sizeData)
				if (b >= 128)
				{
					tagSize = 0;
					TagLibDebugger.Debug("ID3v2.Header.Parse () - One of the size bytes in the id3v2 header was greater than the allowed 128.");
					return;
				}

			// The first three buffer, data[0..2], are the File Identifier, "ID3". (structure 3.1 "file identifier")

			// Read the version number from the fourth and fifth buffer.
			majorVersion = data[3];   // (structure 3.1 "major version")
			revisionNumber = data[4]; // (structure 3.1 "revision number")

			// Read the flags, the first four bits of the sixth byte.
			byte flags = data[5];

			desynchronization = ((flags >> 7) & 1) == 1; // (structure 3.1.a)
			extendedHeader = ((flags >> 6) & 1) == 1; // (structure 3.1.b)
			experimentalIndicator = ((flags >> 5) & 1) == 1; // (structure 3.1.channelMode)
			footerPresent = ((flags >> 4) & 1) == 1; // (structure 3.1.d)

			// Get the size from the remaining four buffer (read above)

			tagSize = Id3v2SynchData.ToUInt(sizeData); // (structure 3.1 "size")
		}
예제 #59
0
        public FrameHeader(ByteVector data, byte version)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            this.flags = FrameFlags.None;
            this.frame_size = 0;
            if ((version < 2) || (version > 4))
            {
                throw new CorruptFileException("Unsupported tag version.");
            }
            if (data.Count < ((version != 2) ? 4 : 3))
            {
                throw new CorruptFileException("Data must contain at least a frame ID.");
            }
            switch (version)
            {
                case 2:
                    this.frame_id = ConvertId(data.Mid(0, 3), version, false);
                    if (data.Count >= 6)
                    {
                        this.frame_size = data.Mid(3, 3).ToUInt();
                        return;
                    }
                    return;

                case 3:
                    this.frame_id = ConvertId(data.Mid(0, 4), version, false);
                    if (data.Count >= 10)
                    {
                        this.frame_size = data.Mid(4, 4).ToUInt();
                        this.flags = (FrameFlags) ((ushort) ((((data[8] << 7) & 0x7000) | ((data[9] >> 4) & 12)) | ((data[9] << 1) & 0x40)));
                        return;
                    }
                    return;

                case 4:
                    this.frame_id = new ReadOnlyByteVector(data.Mid(0, 4));
                    if (data.Count >= 10)
                    {
                        this.frame_size = SynchData.ToUInt(data.Mid(4, 4));
                        this.flags = (FrameFlags) data.Mid(8, 2).ToUShort();
                        return;
                    }
                    return;
            }
            throw new CorruptFileException("Unsupported tag version.");
        }
예제 #60
0
 public override bool ReadPacket (ByteVector packet, int index)
 {
    int type = PacketType (packet);
    if (type != 1 && index == 0)
       throw new CorruptFileException ("Stream does not begin with vorbis identifier");
    
    if (comment_data == null)
    {
       if (type == 1)
          header = new HeaderPacket (packet);
       else if (type == 3)
          comment_data = packet.Mid (7);
       else
          return true;
    }
    
    return comment_data != null;
 }