public void TestTrackCount(StringType stringType) { InfoTag tag; if (stringType == StringType.UTF8) { tag = new TagLib.Riff.InfoTag(); } else { tag = new TagLib.Riff.InfoTag { StringType = stringType } }; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsTrue(t.IsEmpty, "Initial (IsEmpty): " + m); Assert.AreEqual(0, tag.TrackCount, "Initial (Zero): " + m); }); tag.TrackCount = 199; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsFalse(t.IsEmpty, "Value Set (!IsEmpty): " + m); Assert.AreEqual(199, tag.TrackCount, "Value Set: " + m); }); tag.TrackCount = 0; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsTrue(t.IsEmpty, "Value Cleared (IsEmpty): " + m); Assert.AreEqual(0, t.TrackCount, "Value Cleared (Zero): " + m); }); }
void TagTestWithSave(ref TagLib.Riff.InfoTag tag, TagTestFunc testFunc) { testFunc(tag, "Before Save"); //Extras.DumpHex (tag.Render ().Data); tag = new TagLib.Riff.InfoTag(tag.Render()); testFunc(tag, "After Save"); }
public void TestAlbum(StringType stringType) { InfoTag tag; if (stringType == StringType.UTF8) { tag = new TagLib.Riff.InfoTag(); } else { tag = new TagLib.Riff.InfoTag { StringType = stringType } }; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsTrue(t.IsEmpty, "Initial (IsEmpty): " + m); Assert.IsNull(t.Album, "Initial (Null): " + m); }); tag.Album = val_sing; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsFalse(t.IsEmpty, "Value Set (!IsEmpty): " + m); Assert.AreEqual(val_sing, t.Album, "Value Set (!Null): " + m); }); tag.Album = string.Empty; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsTrue(t.IsEmpty, "Value Cleared (IsEmpty): " + m); Assert.IsNull(t.Album, "Value Cleared (Null): " + m); }); }
public void TestClear() { var tag = new TagLib.Riff.InfoTag { Title = "A", Performers = new[] { "B" }, AlbumArtists = new[] { "C" }, Composers = new[] { "D" }, Album = "E", Comment = "F", Genres = new[] { "Blues" }, Year = 123, Track = 234, TrackCount = 234, Disc = 234, DiscCount = 234, Lyrics = "G", Grouping = "H", BeatsPerMinute = 234, Conductor = "I", Copyright = "J", Pictures = new[] { new Picture(TestPath.Covers + "sample_a.png") }, Timecode = "10:30:20:01", TimecodeFrequency = "30", Software = "taglib_sharp", DateTagged = new DateTime(2000, 1, 2, 10, 11, 12) }; Assert.IsFalse(tag.IsEmpty, "Should be full."); tag.Clear(); Assert.IsNull(tag.Title, "Title"); Assert.AreEqual(0, tag.Performers.Length, "Performers"); Assert.AreEqual(0, tag.AlbumArtists.Length, "AlbumArtists"); Assert.AreEqual(0, tag.Composers.Length, "Composers"); Assert.IsNull(tag.Album, "Album"); Assert.IsNull(tag.Comment, "Comment"); Assert.AreEqual(0, tag.Genres.Length, "Genres"); Assert.AreEqual(0, tag.Year, "Year"); Assert.AreEqual(0, tag.Track, "Track"); Assert.AreEqual(0, tag.TrackCount, "TrackCount"); Assert.AreEqual(0, tag.Disc, "Disc"); Assert.AreEqual(0, tag.DiscCount, "DiscCount"); Assert.IsNull(tag.Lyrics, "Lyrics"); Assert.IsNull(tag.Comment, "Comment"); Assert.AreEqual(0, tag.BeatsPerMinute, "BeatsPerMinute"); Assert.IsNull(tag.Conductor, "Conductor"); Assert.IsNull(tag.Copyright, "Copyright"); Assert.AreEqual(0, tag.Pictures.Length, "Pictures"); Assert.IsNull(tag.Timecode, "Timecode"); Assert.IsNull(tag.TimecodeFrequency, "TimecodeFrequency"); Assert.IsNull(tag.Software, "Software"); Assert.IsNull(tag.DateTagged, "DateTagged"); Assert.IsTrue(tag.IsEmpty, "Should be empty."); }
/// <summary> /// Gets a tag of a specified type from the current instance, /// optionally creating a new tag if possible. /// </summary> /// <param name="type"> /// A <see cref="TagLib.TagTypes" /> value indicating the /// type of tag to read. /// </param> /// <param name="create"> /// A <see cref="bool" /> value specifying whether or not to /// try and create the tag if one is not found. /// </param> /// <returns> /// A <see cref="Tag" /> object containing the tag that was /// found in or added to the current instance. If no /// matching tag was found and none was created, <see /// langword="null" /> is returned. /// </returns> public override TagLib.Tag GetTag(TagTypes type, bool create) { TagLib.Tag tag = null; switch (type) { case TagTypes.Id3v2: if (id32_tag == null && create) { id32_tag = new Id3v2.Tag(); id32_tag.Version = 4; id32_tag.Flags |= Id3v2.HeaderFlags .FooterPresent; this.tag.CopyTo(id32_tag, true); } tag = id32_tag; break; case TagTypes.RiffInfo: if (info_tag == null && create) { info_tag = new InfoTag(); this.tag.CopyTo(info_tag, true); } tag = info_tag; break; case TagTypes.MovieId: if (mid_tag == null && create) { mid_tag = new MovieIdTag(); this.tag.CopyTo(mid_tag, true); } tag = mid_tag; break; case TagTypes.DivX: if (divx_tag == null && create) { divx_tag = new DivXTag(); this.tag.CopyTo(divx_tag, true); } tag = divx_tag; break; } this.tag.SetTags(id32_tag, info_tag, mid_tag, divx_tag); return(tag); }
public void TestGenres(StringType stringType) { InfoTag tag; if (stringType == StringType.UTF8) { tag = new TagLib.Riff.InfoTag(); } else { tag = new TagLib.Riff.InfoTag { StringType = stringType } }; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsTrue(t.IsEmpty, "Initial (IsEmpty): " + m); Assert.AreEqual(0, t.Genres.Length, "Initial (Zero): " + m); }); tag.Genres = val_gnre; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsFalse(t.IsEmpty, "Value Set (!IsEmpty): " + m); Assert.AreEqual(val_gnre.Length, t.Genres.Length, "Value Set: " + m); for (int i = 0; i < val_gnre.Length; i++) { Assert.AreEqual(val_gnre[i], t.Genres[i], "Value Set: " + m); } }); tag.Genres = val_mult; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsFalse(t.IsEmpty, "Value Set (!IsEmpty): " + m); Assert.AreEqual(val_mult.Length, t.Genres.Length, "Value Set: " + m); for (int i = 0; i < val_mult.Length; i++) { Assert.AreEqual(val_mult[i], t.Genres[i], "Value Set: " + m); } }); tag.Genres = new string[0]; TagTestWithSave(ref tag, delegate(TagLib.Riff.InfoTag t, string m) { Assert.IsTrue(t.IsEmpty, "Value Cleared (IsEmpty): " + m); Assert.AreEqual(0, t.Genres.Length, "Value Cleared (Zero): " + m); }); }
public void TestClear() { var tag = new TagLib.Riff.InfoTag { Title = "A", Performers = new[] { "B" }, AlbumArtists = new[] { "C" }, Composers = new[] { "D" }, Album = "E", Comment = "F", Genres = new[] { "Blues" }, Year = 123, Track = 234, TrackCount = 234, Disc = 234, DiscCount = 234, Lyrics = "G", Grouping = "H", BeatsPerMinute = 234, Conductor = "I", Copyright = "J", Pictures = new[] { new Picture(TestPath.Covers + "sample_a.png") } }; Assert.IsFalse(tag.IsEmpty, "Should be full."); tag.Clear(); Assert.IsNull(tag.Title, "Title"); Assert.AreEqual(0, tag.Performers.Length, "Performers"); Assert.AreEqual(0, tag.AlbumArtists.Length, "AlbumArtists"); Assert.AreEqual(0, tag.Composers.Length, "Composers"); Assert.IsNull(tag.Album, "Album"); Assert.IsNull(tag.Comment, "Comment"); Assert.AreEqual(0, tag.Genres.Length, "Genres"); Assert.AreEqual(0, tag.Year, "Year"); Assert.AreEqual(0, tag.Track, "Track"); Assert.AreEqual(0, tag.TrackCount, "TrackCount"); Assert.AreEqual(0, tag.Disc, "Disc"); Assert.AreEqual(0, tag.DiscCount, "DiscCount"); Assert.IsNull(tag.Lyrics, "Lyrics"); Assert.IsNull(tag.Comment, "Comment"); Assert.AreEqual(0, tag.BeatsPerMinute, "BeatsPerMinute"); Assert.IsNull(tag.Conductor, "Conductor"); Assert.IsNull(tag.Copyright, "Copyright"); Assert.AreEqual(0, tag.Pictures.Length, "Pictures"); Assert.IsTrue(tag.IsEmpty, "Should be empty."); }
public override TagLib.Tag GetTag(TagTypes type, bool create) { TagLib.Tag tag = null; switch (type) { case (TagTypes.None | TagTypes.Id3v2): if ((this.id32_tag == null) && create) { this.id32_tag = new TagLib.Id3v2.Tag(); this.id32_tag.Version = 4; this.id32_tag.Flags = (HeaderFlags) ((byte) (this.id32_tag.Flags | HeaderFlags.FooterPresent)); this.tag.CopyTo(this.id32_tag, true); } tag = this.id32_tag; break; case TagTypes.RiffInfo: if ((this.info_tag == null) && create) { this.info_tag = new InfoTag(); this.tag.CopyTo(this.info_tag, true); } tag = this.info_tag; break; case TagTypes.MovieId: if ((this.mid_tag == null) && create) { this.mid_tag = new MovieIdTag(); this.tag.CopyTo(this.mid_tag, true); } tag = this.mid_tag; break; case TagTypes.DivX: if ((this.divx_tag == null) && create) { this.divx_tag = new DivXTag(); this.tag.CopyTo(this.divx_tag, true); } tag = this.divx_tag; break; } TagLib.Tag[] tags = new TagLib.Tag[] { this.id32_tag, this.info_tag, this.mid_tag, this.divx_tag }; this.tag.SetTags(tags); return tag; }
public override void RemoveTags(TagTypes types) { if ((types & TagLib.TagTypes.Id3v2) != TagLib.TagTypes.None) { id32_tag = null; } if ((types & TagLib.TagTypes.RiffInfo) != TagLib.TagTypes.None) { info_tag = null; } if ((types & TagLib.TagTypes.MovieId) != TagLib.TagTypes.None) { mid_tag = null; } if ((types & TagLib.TagTypes.DivX) != TagLib.TagTypes.None) { divx_tag = null; } tag.SetTags(id32_tag, info_tag, mid_tag, divx_tag); }
/// <summary> /// Reads the contents of the current instance determining /// the size of the riff data, the area the tagging is in, /// and optionally reading in the tags and media properties. /// </summary> /// <param name="read_tags"> /// If <see langword="true" />, any tags found will be read /// into the current instance. /// </param> /// <param name="style"> /// A <see cref="ReadStyle"/> value specifying how the media /// data is to be read into the current instance. /// </param> /// <param name="riff_size"> /// A <see cref="uint"/> value reference to be filled with /// the size of the RIFF data as read from the file. /// </param> /// <param name="tag_start"> /// A <see cref="long" /> value reference to be filled with /// the absolute seek position at which the tagging data /// starts. /// </param> /// <param name="tag_end"> /// A <see cref="long" /> value reference to be filled with /// the absolute seek position at which the tagging data /// ends. /// </param> /// <exception cref="CorruptFileException"> /// The file does not begin with <see cref="FileIdentifier" /// />. /// </exception> private void Read(bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end) { Seek (0); if (ReadBlock (4) != FileIdentifier) throw new CorruptFileException ( "File does not begin with RIFF identifier"); riff_size = ReadBlock (4).ToUInt (false); ByteVector stream_format = ReadBlock (4); tag_start = -1; tag_end = -1; long position = 12; long length = Length; uint size = 0; TimeSpan duration = TimeSpan.Zero; ICodec [] codecs = new ICodec [0]; // Read until there are less than 8 bytes to read. do { bool tag_found = false; Seek (position); string fourcc = ReadBlock (4).ToString (StringType.UTF8); size = ReadBlock (4).ToUInt (false); switch (fourcc) { // "fmt " is used by Wave files to hold the // WaveFormatEx structure. case "fmt ": if (style == ReadStyle.None || stream_format != "WAVE") break; Seek (position + 8); codecs = new ICodec [] { new WaveFormatEx (ReadBlock (18), 0) }; break; // "data" contains the audio data for wave // files. It's contents represent the invariant // portion of the file and is used to determine // the duration of a file. It should always // appear after "fmt ". case "data": if (stream_format != "WAVE") break; InvariantStartPosition = position; InvariantEndPosition = position + size; if (style == ReadStyle.None || codecs.Length != 1 || !(codecs [0] is WaveFormatEx)) break; duration += TimeSpan.FromSeconds ( (double) size / (double) ((WaveFormatEx) codecs [0]) .AverageBytesPerSecond); break; // Lists are used to store a variety of data // collections. Read the type and act on it. case "LIST": { switch (ReadBlock (4).ToString (StringType.UTF8)) { // "hdlr" is used by AVI files to hold // a media header and BitmapInfoHeader // and WaveFormatEx structures. case "hdrl": if (style == ReadStyle.None || stream_format != "AVI ") continue; AviHeaderList header_list = new AviHeaderList (this, position + 12, (int) (size - 4)); duration = header_list.Header.Duration; codecs = header_list.Codecs; break; // "INFO" is a tagging format handled by // the InfoTag class. case "INFO": if (read_tags && info_tag == null) info_tag = new InfoTag ( this, position + 12, (int) (size - 4)); tag_found = true; break; // "MID " is a tagging format handled by // the MovieIdTag class. case "MID ": if (read_tags && mid_tag == null) mid_tag = new MovieIdTag ( this, position + 12, (int) (size - 4)); tag_found = true; break; // "movi" contains the media data for // and AVI and its contents represent // the invariant portion of the file. case "movi": if (stream_format != "AVI ") break; InvariantStartPosition = position; InvariantEndPosition = position + size; break; } break; } // "ID32" is a custom box for this format that // contains an ID3v2 tag. case "ID32": if (read_tags && id32_tag == null) id32_tag = new Id3v2.Tag (this, position + 8); tag_found = true; break; // "IDVX" is used by DivX and holds an ID3v1- // style tag. case "IDVX": if (read_tags && divx_tag == null) divx_tag = new DivXTag (this, position + 8); tag_found = true; break; // "JUNK" is a padding element that could be // associated with tag data. case "JUNK": if (tag_end == position) tag_end = position + 8 + size; break; } // Determine the region of the file that // contains tags. if (tag_found) { if (tag_start == -1) { tag_start = position; tag_end = position + 8 + size; } else if (tag_end == position) { tag_end = position + 8 + size; } } // Move to the next item. } while ((position += 8 + size) + 8 < length); // If we're reading properties, and one were found, // throw an exception. Otherwise, create the Properties // object. if (style != ReadStyle.None) { if (codecs.Length == 0) throw new UnsupportedFormatException ( "Unsupported RIFF type."); properties = new Properties (duration, codecs); } // If we're reading tags, update the combined tag. if (read_tags) tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag); }
/// <summary> /// Gets a tag of a specified type from the current instance, /// optionally creating a new tag if possible. /// </summary> /// <param name="type"> /// A <see cref="TagLib.TagTypes" /> value indicating the /// type of tag to read. /// </param> /// <param name="create"> /// A <see cref="bool" /> value specifying whether or not to /// try and create the tag if one is not found. /// </param> /// <returns> /// A <see cref="Tag" /> object containing the tag that was /// found in or added to the current instance. If no /// matching tag was found and none was created, <see /// langword="null" /> is returned. /// </returns> public override TagLib.Tag GetTag(TagTypes type, bool create) { TagLib.Tag tag = null; switch (type) { case TagTypes.Id3v2: if (id32_tag == null && create) { id32_tag = new Id3v2.Tag (); id32_tag.Version = 4; id32_tag.Flags |= Id3v2.HeaderFlags .FooterPresent; this.tag.CopyTo (id32_tag, true); } tag = id32_tag; break; case TagTypes.RiffInfo: if (info_tag == null && create) { info_tag = new InfoTag (); this.tag.CopyTo (info_tag, true); } tag = info_tag; break; case TagTypes.MovieId: if (mid_tag == null && create) { mid_tag = new MovieIdTag (); this.tag.CopyTo (mid_tag, true); } tag = mid_tag; break; case TagTypes.DivX: if (divx_tag == null && create) { divx_tag = new DivXTag (); this.tag.CopyTo (divx_tag, true); } tag = divx_tag; break; } this.tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag); return tag; }
/// <summary> /// Removes a set of tag types from the current instance. /// </summary> /// <param name="types"> /// A bitwise combined <see cref="TagLib.TagTypes" /> value /// containing tag types to be removed from the file. /// </param> /// <remarks> /// In order to remove all tags from a file, pass <see /// cref="TagTypes.AllTags" /> as <paramref name="types" />. /// </remarks> public override void RemoveTags(TagTypes types) { if ((types & TagLib.TagTypes.Id3v2) != TagLib.TagTypes.None) id32_tag = null; if ((types & TagLib.TagTypes.RiffInfo) != TagLib.TagTypes.None) info_tag = null; if ((types & TagLib.TagTypes.MovieId) != TagLib.TagTypes.None) mid_tag = null; if ((types & TagLib.TagTypes.DivX) != TagLib.TagTypes.None) divx_tag = null; tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag); }
private void Read(bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end) { bool flag; base.Seek(0L); if (base.ReadBlock(4) != FileIdentifier) { throw new CorruptFileException("File does not begin with RIFF identifier"); } riff_size = base.ReadBlock(4).ToUInt(false); ByteVector vector = base.ReadBlock(4); tag_start = -1L; tag_end = -1L; long offset = 12L; long length = base.Length; uint num3 = 0; TimeSpan zero = TimeSpan.Zero; ICodec[] codecs = new ICodec[0]; Label_0066: flag = false; base.Seek(offset); string str = base.ReadBlock(4).ToString(StringType.UTF8); num3 = base.ReadBlock(4).ToUInt(false); string key = str; if (key != null) { Dictionary<string, int> dictionary; int num4; if (<>f__switch$map3 == null) { dictionary = new Dictionary<string, int>(6); dictionary.Add("fmt ", 0); dictionary.Add("data", 1); dictionary.Add("LIST", 2); dictionary.Add("ID32", 3); dictionary.Add("IDVX", 4); dictionary.Add("JUNK", 5); <>f__switch$map3 = dictionary; } if (<>f__switch$map3.TryGetValue(key, out num4)) { switch (num4) { case 0: if ((style != ReadStyle.None) && (vector == "WAVE")) { base.Seek(offset + 8L); codecs = new ICodec[] { new WaveFormatEx(base.ReadBlock(0x12), 0) }; break; } break; case 1: if (vector == "WAVE") { base.InvariantStartPosition = offset; base.InvariantEndPosition = offset + num3; if (((style != ReadStyle.None) && (codecs.Length == 1)) && (codecs[0] is WaveFormatEx)) { WaveFormatEx ex = (WaveFormatEx) codecs[0]; zero += TimeSpan.FromSeconds(((double) num3) / ((double) ex.AverageBytesPerSecond)); } break; } break; case 2: { string str3 = base.ReadBlock(4).ToString(StringType.UTF8); if (str3 != null) { int num5; if (<>f__switch$map2 == null) { dictionary = new Dictionary<string, int>(4); dictionary.Add("hdrl", 0); dictionary.Add("INFO", 1); dictionary.Add("MID ", 2); dictionary.Add("movi", 3); <>f__switch$map2 = dictionary; } if (<>f__switch$map2.TryGetValue(str3, out num5)) { switch (num5) { case 0: if ((style != ReadStyle.None) && (vector == "AVI ")) { AviHeaderList list = new AviHeaderList(this, offset + 12L, ((int) num3) - 4); zero = list.Header.Duration; codecs = list.Codecs; break; } goto Label_040E; case 1: if (read_tags && (this.info_tag == null)) { this.info_tag = new InfoTag(this, offset + 12L, ((int) num3) - 4); } flag = true; break; case 2: if (read_tags && (this.mid_tag == null)) { this.mid_tag = new MovieIdTag(this, offset + 12L, ((int) num3) - 4); } flag = true; break; case 3: if (vector == "AVI ") { base.InvariantStartPosition = offset; base.InvariantEndPosition = offset + num3; break; } break; } } } break; } case 3: if (read_tags && (this.id32_tag == null)) { this.id32_tag = new TagLib.Id3v2.Tag(this, offset + 8L); } flag = true; break; case 4: if (read_tags && (this.divx_tag == null)) { this.divx_tag = new DivXTag(this, offset + 8L); } flag = true; break; case 5: if (tag_end == offset) { tag_end = (offset + 8L) + num3; } break; } } } if (flag) { if (tag_start == -1L) { tag_start = offset; tag_end = (offset + 8L) + num3; } else if (tag_end == offset) { tag_end = (offset + 8L) + num3; } } Label_040E: if (((offset += (8 + num3)) + 8L) < length) { goto Label_0066; } if (style != ReadStyle.None) { if (codecs.Length == 0) { throw new UnsupportedFormatException("Unsupported RIFF type."); } this.properties = new TagLib.Properties(zero, codecs); } if (read_tags) { TagLib.Tag[] tags = new TagLib.Tag[] { this.id32_tag, this.info_tag, this.mid_tag, this.divx_tag }; this.tag.SetTags(tags); } }
public override void RemoveTags(TagTypes types) { if ((types & (TagTypes.None | TagTypes.Id3v2)) != TagTypes.None) { this.id32_tag = null; } if ((types & TagTypes.RiffInfo) != TagTypes.None) { this.info_tag = null; } if ((types & TagTypes.MovieId) != TagTypes.None) { this.mid_tag = null; } if ((types & TagTypes.DivX) != TagTypes.None) { this.divx_tag = null; } TagLib.Tag[] tags = new TagLib.Tag[] { this.id32_tag, this.info_tag, this.mid_tag, this.divx_tag }; this.tag.SetTags(tags); }
private void Read (bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end) { Seek (0); if (ReadBlock (4) != FileIdentifier) throw new CorruptFileException ("File does not begin with RIFF identifier"); riff_size = ReadBlock (4).ToUInt (false); ByteVector stream_format = ReadBlock (4); tag_start = -1; tag_end = -1; long position = 12; long length = Length; TimeSpan duration = TimeSpan.Zero; ICodec[] codecs = new ICodec [0]; do { bool tag_found = false; Seek (position); string fourcc = ReadBlock (4).ToString (StringType.UTF8); uint size = ReadBlock (4).ToUInt (false); switch (fourcc) { case "fmt ": if (stream_format == "WAVE" && style != ReadStyle.None) { Seek (position + 8); codecs = new ICodec [] {new WaveFormatEx (ReadBlock (18), 0)}; } break; case "data": if (stream_format == "WAVE") { if (style != ReadStyle.None && codecs.Length == 1 && codecs [0] is WaveFormatEx) duration += TimeSpan.FromSeconds ((double) size / (double) ((WaveFormatEx) codecs [0]).AverageBytesPerSecond); InvariantStartPosition = position; InvariantEndPosition = position + size; } break; case "LIST": { switch (ReadBlock (4).ToString (StringType.UTF8)) { case "hdrl": if (stream_format == "AVI " && style != ReadStyle.None) { AviHeaderList header_list = new AviHeaderList (this, position + 12, (int) (size - 4)); duration = header_list.Header.Duration; codecs = header_list.Codecs; } break; case "INFO": { if (read_tags && info_tag == null) info_tag = new InfoTag (this, position + 12, (int) (size - 4)); tag_found = true; break; } case "MID ": if (read_tags && mid_tag == null) mid_tag = new MovieIdTag (this, position + 12, (int) (size - 4)); tag_found = true; break; case "movi": if (stream_format == "AVI ") { InvariantStartPosition = position; InvariantEndPosition = position + size; } break; } break; } case "ID32": if (read_tags && id32_tag == null) id32_tag = new Id3v2.Tag (this, position + 8); tag_found = true; break; case "IDVX": if (read_tags && divx_tag == null) divx_tag = new DivXTag (this, position + 8); tag_found = true; break; case "JUNK": if (tag_end == position) tag_end = position + 8 + size; break; } if (tag_found) { if (tag_start == -1) { tag_start = position; tag_end = position + 8 + size; } else if (tag_end == position) tag_end = position + 8 + size; } position += 8 + size; } while (position + 8 < length); if (style != ReadStyle.None) { if (codecs.Length == 0) throw new UnsupportedFormatException ("Unsupported RIFF type."); properties = new Properties (duration, codecs); } if (read_tags) tag.SetTags (id32_tag, info_tag, mid_tag, divx_tag); }
/// <summary> /// Reads the contents of the current instance determining /// the size of the riff data, the area the tagging is in, /// and optionally reading in the tags and media properties. /// </summary> /// <param name="read_tags"> /// If <see langword="true" />, any tags found will be read /// into the current instance. /// </param> /// <param name="style"> /// A <see cref="ReadStyle"/> value specifying how the media /// data is to be read into the current instance. /// </param> /// <param name="riff_size"> /// A <see cref="uint"/> value reference to be filled with /// the size of the RIFF data as read from the file. /// </param> /// <param name="tag_start"> /// A <see cref="long" /> value reference to be filled with /// the absolute seek position at which the tagging data /// starts. /// </param> /// <param name="tag_end"> /// A <see cref="long" /> value reference to be filled with /// the absolute seek position at which the tagging data /// ends. /// </param> /// <exception cref="CorruptFileException"> /// The file does not begin with <see cref="FileIdentifier" /// />. /// </exception> private void Read(bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end) { Seek(0); if (ReadBlock(4) != FileIdentifier) { throw new CorruptFileException( "File does not begin with RIFF identifier"); } riff_size = ReadBlock(4).ToUInt(false); ByteVector stream_format = ReadBlock(4); tag_start = -1; tag_end = -1; long position = 12; long length = Length; uint size = 0; TimeSpan duration = TimeSpan.Zero; ICodec [] codecs = new ICodec [0]; // Read until there are less than 8 bytes to read. do { bool tag_found = false; Seek(position); string fourcc = ReadBlock(4).ToString(StringType.UTF8); size = ReadBlock(4).ToUInt(false); switch (fourcc) { // "fmt " is used by Wave files to hold the // WaveFormatEx structure. case "fmt ": if (style == ReadStyle.None || stream_format != "WAVE") { break; } Seek(position + 8); codecs = new ICodec [] { new WaveFormatEx(ReadBlock(18), 0) }; break; // "data" contains the audio data for wave // files. It's contents represent the invariant // portion of the file and is used to determine // the duration of a file. It should always // appear after "fmt ". case "data": if (stream_format != "WAVE") { break; } InvariantStartPosition = position; InvariantEndPosition = position + size; if (style == ReadStyle.None || codecs.Length != 1 || !(codecs [0] is WaveFormatEx)) { break; } duration += TimeSpan.FromSeconds( (double)size / (double) ((WaveFormatEx)codecs [0]) .AverageBytesPerSecond); break; // Lists are used to store a variety of data // collections. Read the type and act on it. case "LIST": { switch (ReadBlock(4).ToString(StringType.UTF8)) { // "hdlr" is used by AVI files to hold // a media header and BitmapInfoHeader // and WaveFormatEx structures. case "hdrl": if (style == ReadStyle.None || stream_format != "AVI ") { continue; } AviHeaderList header_list = new AviHeaderList(this, position + 12, (int)(size - 4)); duration = header_list.Header.Duration; codecs = header_list.Codecs; break; // "INFO" is a tagging format handled by // the InfoTag class. case "INFO": if (read_tags && info_tag == null) { info_tag = new InfoTag( this, position + 12, (int)(size - 4)); } tag_found = true; break; // "MID " is a tagging format handled by // the MovieIdTag class. case "MID ": if (read_tags && mid_tag == null) { mid_tag = new MovieIdTag( this, position + 12, (int)(size - 4)); } tag_found = true; break; // "movi" contains the media data for // and AVI and its contents represent // the invariant portion of the file. case "movi": if (stream_format != "AVI ") { break; } InvariantStartPosition = position; InvariantEndPosition = position + size; break; } break; } // "ID32" is a custom box for this format that // contains an ID3v2 tag. case "ID32": if (read_tags && id32_tag == null) { id32_tag = new Id3v2.Tag(this, position + 8); } tag_found = true; break; // "IDVX" is used by DivX and holds an ID3v1- // style tag. case "IDVX": if (read_tags && divx_tag == null) { divx_tag = new DivXTag(this, position + 8); } tag_found = true; break; // "JUNK" is a padding element that could be // associated with tag data. case "JUNK": if (tag_end == position) { tag_end = position + 8 + size; } break; } // Determine the region of the file that // contains tags. if (tag_found) { if (tag_start == -1) { tag_start = position; tag_end = position + 8 + size; } else if (tag_end == position) { tag_end = position + 8 + size; } } // Move to the next item. } while ((position += 8 + (long)size) + 8 < length); // If we're reading properties, and one were found, // throw an exception. Otherwise, create the Properties // object. if (style != ReadStyle.None) { if (codecs.Length == 0) { throw new UnsupportedFormatException( "Unsupported RIFF type."); } properties = new Properties(duration, codecs); } // If we're reading tags, update the combined tag. if (read_tags) { tag.SetTags(id32_tag, info_tag, mid_tag, divx_tag); } }
private void Read(bool read_tags, ReadStyle style, out uint riff_size, out long tag_start, out long tag_end) { Seek(0); if (ReadBlock(4) != FileIdentifier) { throw new CorruptFileException("File does not begin with RIFF identifier"); } riff_size = ReadBlock(4).ToUInt(false); ByteVector stream_format = ReadBlock(4); tag_start = -1; tag_end = -1; long position = 12; long length = Length; uint size = 0; TimeSpan duration = TimeSpan.Zero; ICodec[] codecs = new ICodec[0]; do { bool tag_found = false; Seek(position); string fourcc = ReadBlock(4).ToString(StringType.UTF8); size = ReadBlock(4).ToUInt(false); switch (fourcc) { case "fmt ": if (style == ReadStyle.None || stream_format != "WAVE") { break; } Seek(position + 8); codecs = new ICodec[] { new WaveFormatEx(ReadBlock(18), 0) }; break; case "data": if (stream_format != "WAVE") { break; } InvariantStartPosition = position; InvariantEndPosition = position + size; if (style == ReadStyle.None || codecs.Length != 1 || !(codecs[0] is WaveFormatEx)) { break; } duration += TimeSpan.FromSeconds((double)size / (double)((WaveFormatEx)codecs[0]).AverageBytesPerSecond); break; case "LIST": { switch (ReadBlock(4).ToString(StringType.UTF8)) { case "hdrl": if (style == ReadStyle.None || stream_format != "AVI ") { continue; } AviHeaderList header_list = new AviHeaderList(this, position + 12, (int)(size - 4)); duration = header_list.Header.Duration; codecs = header_list.Codecs; break; case "INFO": if (read_tags && info_tag == null) { info_tag = new InfoTag(this, position + 12, (int)(size - 4)); } tag_found = true; break; case "MID ": if (read_tags && mid_tag == null) { mid_tag = new MovieIdTag(this, position + 12, (int)(size - 4)); } tag_found = true; break; case "movi": if (stream_format != "AVI ") { break; } InvariantStartPosition = position; InvariantEndPosition = position + size; break; } break; } case "ID32": if (read_tags && id32_tag == null) { id32_tag = new Id3v2.Tag(this, position + 8); } tag_found = true; break; case "IDVX": if (read_tags && divx_tag == null) { divx_tag = new DivXTag(this, position + 8); } tag_found = true; break; case "JUNK": if (tag_end == position) { tag_end = position + 8 + size; } break; } if (tag_found) { if (tag_start == -1) { tag_start = position; tag_end = position + 8 + size; } else if (tag_end == position) { tag_end = position + 8 + size; } } }while((position += 8 + size) + 8 < length); if (style != ReadStyle.None) { if (codecs.Length == 0) { throw new UnsupportedFormatException("Unsupported RIFF type."); } properties = new Properties(duration, codecs); } if (read_tags) { tag.SetTags(id32_tag, info_tag, mid_tag, divx_tag); } }