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; }
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; }
//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); }
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"); }
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; }
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); } }
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); }
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"); }
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); }
protected void Parse (ByteVector data, byte version) { if (data == null) throw new ArgumentNullException ("data"); size = SynchData.ToUInt (data.Mid (0, 4)); }
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; }
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)); }
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; }
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); }
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)); }
/// <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(); }
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); }
/// <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); }
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; }
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); }
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); }
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); }
/// <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); }
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); }
/// <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); }
/// <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); }
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); }
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); }
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 (); }
/// <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(); }
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); } } }
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); }
/// <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); }
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(); }
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; }
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); }
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; }
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); }
/// <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]; }
/// <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; } }
/// <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; }
/// <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)); }
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); }
/// <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); }
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()); }
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; }
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(); }
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); }
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") }
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."); }
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; }