public Id3v2Tag() : base() { tagOffset = -1; header = new Id3v2Header(); //extendedHeader = null; //footer = null; frameList = new ArrayList(); }
public Id3v2Footer(Id3v2Header header) : this() { if (header != null) { majorVersion = header.MajorVersion; revisionNumber = header.RevisionNumber; desynchronization = header.Desynchronization; extendedHeader = header.ExtendedHeader; experimentalIndicator = header.ExperimentalIndicator; tagSize = header.TagSize; } }
public override void Save() { if (IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; // Update ID3v2 tag long id3v2_location = FindId3v2(); int id3v2_size = 0; if (id3v2_location != -1) { Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) { TagLibDebugger.Debug("Mpc.File.Save() -- Id3v2 header is broken. Ignoring."); id3v2_location = -1; } else { id3v2_size = (int)header.CompleteTagSize; } } if (id3v2Tag != null) { if (id3v2_location >= 0) { Insert(id3v2Tag.Render(), id3v2_location, id3v2_size); } else { Insert(id3v2Tag.Render(), 0, 0); } } else if (id3v2_location >= 0) { RemoveBlock(id3v2_location, id3v2_size); } // Update ID3v1 tag long id3v1_location = FindId3v1(); if (id3v1Tag != null) { if (id3v1_location >= 0) { Insert(id3v1Tag.Render(), id3v1_location, 128); } else { Seek(0, System.IO.SeekOrigin.End); id3v1_location = Tell; WriteBlock(id3v1Tag.Render()); } } else if (id3v1_location >= 0) { RemoveBlock(id3v1_location, 128); id3v1_location = -1; } // Update APE tag long ape_location = FindApe(id3v1_location != -1); long ape_size = 0; if (ape_location >= 0) { Seek(ape_location); ape_size = (new ApeFooter(ReadBlock((int)ApeFooter.Size))).CompleteTagSize; ape_location = ape_location + ApeFooter.Size - ape_size; } if (apeTag != null) { if (ape_location >= 0) { Insert(apeTag.Render(), ape_location, ape_size); } else { if (id3v1_location >= 0) { Insert(apeTag.Render(), id3v1_location, 0); } else { Seek(0, System.IO.SeekOrigin.End); WriteBlock(apeTag.Render()); } } } else if (ape_location >= 0) { RemoveBlock(ape_location, ape_size); } Mode = FileAccessMode.Closed; }
public override void Save() { if (IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; long flac_data_begin; long flac_data_end; // Update ID3 tags if (id3v2_tag != null) { ByteVector id3v2_tag_data = id3v2_tag.Render(); long id3v2_location = FindId3v2(); if (id3v2_location >= 0) { int id3v2_size = 0; Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) TagLibDebugger.Debug("Flac.File.Save() -- Id3v2 header is broken. Ignoring."); else id3v2_size = (int)header.CompleteTagSize; Insert(id3v2_tag_data, id3v2_location, id3v2_size); System.Console.WriteLine("ID3v2: " + id3v2_size + " " + id3v2_tag_data.Count); flac_data_begin = id3v2_location + id3v2_tag_data.Count; } else { Insert(id3v2_tag_data, 0, 0); flac_data_begin = id3v2_tag_data.Count; } } else flac_data_begin = 0; if (id3v1_tag != null) { long id3v1_location = FindId3v1(); if (id3v1_location >= 0) Seek(id3v1_location); else Seek(0, System.IO.SeekOrigin.End); flac_data_end = Tell; WriteBlock(id3v1_tag.Render()); } else flac_data_end = Length; // Create new vorbis comments is they don'type exist. FindTag(TagTypes.Xiph, true); xiph_comment_data = comment.Render(false); ByteVector v = ByteVector.FromUInt((uint)xiph_comment_data.Count); // Set the type of the comment to be a Xiph / Vorbis comment // (See scan() for comments on header-format) v[0] = 4; v.Add(xiph_comment_data); // If file already have comment => find and update it // if not => insert one scanned = false; if (Scan(flac_data_begin, flac_data_end) != null) { long next_page_offset = flac_start; Seek(next_page_offset); ByteVector header = ReadBlock(4); uint length = header.Mid(1, 3).ToUInt(); next_page_offset += length + 4; // Search through the remaining metadata byte block_type = (byte)(header[0] & 0x7f); bool last_block = (header[0] & 0x80) != 0; while (!last_block) { Seek(next_page_offset); header = ReadBlock(4); block_type = (byte)(header[0] & 0x7f); last_block = (header[0] & 0x80) != 0; length = header.Mid(1, 3).ToUInt(); // Type is vorbiscomment if (block_type == 4) { long next_keep = (last_block ? 0 : FindPaddingBreak(next_page_offset + length + 4, next_page_offset + XiphCommentData.Count + 8, ref last_block)); uint padding_length; if (next_keep != 0) { // There is space for comment and padding blocks without rewriting the whole file. // Note this can not overflow. padding_length = (uint)(next_keep - (next_page_offset + XiphCommentData.Count + 8)); } else { // Not enough space, so we will have to rewrite the whole file following this block padding_length = (uint)XiphCommentData.Count; if (padding_length < 4096) padding_length = 4096; next_keep = next_page_offset + length + 4; } ByteVector padding = ByteVector.FromUInt(padding_length); padding[0] = 1; if (last_block) padding[0] = (byte)(padding[0] | 0x80); padding.Resize((int)(padding_length + 4)); Insert(v + padding, next_page_offset, next_keep - next_page_offset); //System.Console.WriteLine ("OGG: " + (next_keep - next_page_offset) + " " + (vector.Count + padding.Count)); break; } next_page_offset += length + 4; } } else { long next_page_offset = flac_start; Seek(next_page_offset); ByteVector header = ReadBlock(4); bool last_block = (header[0] & 0x80) != 0; uint length = header.Mid(1, 3).ToUInt(); // If last block was last, make this one last if (last_block) { // Copy the bottom seven bits into the new value ByteVector h = (byte)(header[0] & 0x7F); Insert(h, next_page_offset, 1); // Set the last bit v[0] = (byte)(v[0] | 0x80); } Insert(v, next_page_offset + length + 4, 0); } Mode = FileAccessMode.Closed; }
public override void Save() { if (IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; long flac_data_begin; long flac_data_end; // Update ID3 tags if (id3v2_tag != null) { ByteVector id3v2_tag_data = id3v2_tag.Render(); long id3v2_location = FindId3v2(); if (id3v2_location >= 0) { int id3v2_size = 0; Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) { TagLibDebugger.Debug("Flac.File.Save() -- Id3v2 header is broken. Ignoring."); } else { id3v2_size = (int)header.CompleteTagSize; } Insert(id3v2_tag_data, id3v2_location, id3v2_size); System.Console.WriteLine("ID3v2: " + id3v2_size + " " + id3v2_tag_data.Count); flac_data_begin = id3v2_location + id3v2_tag_data.Count; } else { Insert(id3v2_tag_data, 0, 0); flac_data_begin = id3v2_tag_data.Count; } } else { flac_data_begin = 0; } if (id3v1_tag != null) { long id3v1_location = FindId3v1(); if (id3v1_location >= 0) { Seek(id3v1_location); } else { Seek(0, System.IO.SeekOrigin.End); } flac_data_end = Tell; WriteBlock(id3v1_tag.Render()); } else { flac_data_end = Length; } // Create new vorbis comments is they don'type exist. FindTag(TagTypes.Xiph, true); xiph_comment_data = comment.Render(false); ByteVector v = ByteVector.FromUInt((uint)xiph_comment_data.Count); // Set the type of the comment to be a Xiph / Vorbis comment // (See scan() for comments on header-format) v[0] = 4; v.Add(xiph_comment_data); // If file already have comment => find and update it // if not => insert one scanned = false; if (Scan(flac_data_begin, flac_data_end) != null) { long next_page_offset = flac_start; Seek(next_page_offset); ByteVector header = ReadBlock(4); uint length = header.Mid(1, 3).ToUInt(); next_page_offset += length + 4; // Search through the remaining metadata byte block_type = (byte)(header[0] & 0x7f); bool last_block = (header[0] & 0x80) != 0; while (!last_block) { Seek(next_page_offset); header = ReadBlock(4); block_type = (byte)(header[0] & 0x7f); last_block = (header[0] & 0x80) != 0; length = header.Mid(1, 3).ToUInt(); // Type is vorbiscomment if (block_type == 4) { long next_keep = (last_block ? 0 : FindPaddingBreak(next_page_offset + length + 4, next_page_offset + XiphCommentData.Count + 8, ref last_block)); uint padding_length; if (next_keep != 0) { // There is space for comment and padding blocks without rewriting the whole file. // Note this can not overflow. padding_length = (uint)(next_keep - (next_page_offset + XiphCommentData.Count + 8)); } else { // Not enough space, so we will have to rewrite the whole file following this block padding_length = (uint)XiphCommentData.Count; if (padding_length < 4096) { padding_length = 4096; } next_keep = next_page_offset + length + 4; } ByteVector padding = ByteVector.FromUInt(padding_length); padding[0] = 1; if (last_block) { padding[0] = (byte)(padding[0] | 0x80); } padding.Resize((int)(padding_length + 4)); Insert(v + padding, next_page_offset, next_keep - next_page_offset); //System.Console.WriteLine ("OGG: " + (next_keep - next_page_offset) + " " + (vector.Count + padding.Count)); break; } next_page_offset += length + 4; } } else { long next_page_offset = flac_start; Seek(next_page_offset); ByteVector header = ReadBlock(4); bool last_block = (header[0] & 0x80) != 0; uint length = header.Mid(1, 3).ToUInt(); // If last block was last, make this one last if (last_block) { // Copy the bottom seven bits into the new value ByteVector h = (byte)(header[0] & 0x7F); Insert(h, next_page_offset, 1); // Set the last bit v[0] = (byte)(v[0] | 0x80); } Insert(v, next_page_offset + length + 4, 0); } Mode = FileAccessMode.Closed; }
public bool Strip (TagTypes types, bool freeMemory) { FileAccessMode original_mode = Mode; if(IsReadOnly) { TagLibDebugger.Debug("Mpeg.File.Strip() - Cannot strip tags from a read only file."); return false; } try { Mode = FileAccessMode.Write; } catch (TagLibException) { TagLibDebugger.Debug("Mpeg.File.Strip() - Cannot strip tags from a read only file."); return false; } if ((types & TagTypes.Id3v2) != 0) { long id3v2_location = FindId3v2 (); if (id3v2_location >= 0) { Seek(id3v2_location); Id3v2Header header = new Id3v2Header (ReadBlock ((int)Id3v2Header.Size)); if (header.TagSize == 0) TagLibDebugger.Debug ("Mpc.File.Save() -- Id3v2 header is broken. Ignoring."); else RemoveBlock (id3v2_location, (int) header.CompleteTagSize); } if (freeMemory) id3v2_tag = null; } long id3v1_location = FindId3v1 (); if ((types & TagTypes.Id3v1) != 0) { if (id3v1_location >= 0) { Truncate(id3v1_location); id3v1_location = -1; } if (freeMemory) id3v1_tag = null; } if ((types & TagTypes.Ape) != 0) { long ape_location = FindApe (id3v1_location >= 0); if (ape_location != -1) { Seek(ape_location); int ape_size = (int) (new ApeFooter(ReadBlock((int) ApeFooter.Size))).CompleteTagSize; ape_location = ape_location + ApeFooter.Size - ape_size; RemoveBlock(ape_location, ape_size); } if (freeMemory) ape_tag = null; } tag.SetTags(id3v2_tag, ape_tag, id3v1_tag); Mode = original_mode; return true; }
public void Save(TagTypes types, bool stripOthers) { if (types == TagTypes.None && stripOthers) { if(!Strip(TagTypes.AllTags)) throw new TagLibException(TagLibError.MpegCouldNotStripTags); return; } if (id3v2_tag == null && id3v1_tag == null && ape_tag == null) { if (stripOthers) { if(!Strip (TagTypes.AllTags)) throw new TagLibException(TagLibError.MpegCouldNotStripTags); } return; } if(IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; // Create the tags if we've been asked to. Copy the values from the tag that // does exist into the new tag. if ((types & TagTypes.Id3v2) != 0 && id3v1_tag != null) TagLib.Tag.Duplicate (id3v1_tag, FindTag (TagTypes.Id3v2, true), false); if ((types & TagTypes.Id3v1) != 0 && id3v2_tag != null) TagLib.Tag.Duplicate (id3v2_tag, FindTag (TagTypes.Id3v1, true), false); bool success = true; if ((TagTypes.Id3v2 & types) != 0 && id3v2_tag != null && !id3v2_tag.IsEmpty) { long id3v2_location = FindId3v2 (); int id3v2_size = 0; if (id3v2_location < 0) id3v2_location = 0; else { Seek (id3v2_location); Id3v2Header header = new Id3v2Header (ReadBlock ((int)Id3v2Header.Size)); if (header.TagSize == 0) TagLibDebugger.Debug ("Mpc.File.Save() -- Id3v2 header is broken. Ignoring."); else id3v2_size = (int) header.CompleteTagSize; } Insert (id3v2_tag.Render (), id3v2_location, id3v2_size); } else if (stripOthers) success = Strip (TagTypes.Id3v2) && success; if ((TagTypes.Id3v1 & types) != 0 && id3v1_tag != null && !id3v1_tag.IsEmpty) { long id3v1_location = FindId3v1 (); if (id3v1_location < 0) Seek (0, System.IO.SeekOrigin.End); else Seek (id3v1_location); WriteBlock (id3v1_tag.Render ()); } else if (stripOthers) success = (Strip(TagTypes.Id3v1, false) && success); // Dont save an APE-tag unless one has been created if((TagTypes.Ape & types) != 0 && ape_tag != null && !ape_tag.IsEmpty) { long ape_location = FindApe (FindId3v1 () >= 0); long ape_size = 0; if (ape_location < 0) ape_location = Length; else { Seek(ape_location); ape_size = (new ApeFooter(ReadBlock((int)ApeFooter.Size))).CompleteTagSize; ape_location = ape_location + ApeFooter.Size - ape_size; } Insert (ape_tag.Render (), ape_location, ape_size); } else if(stripOthers) success = (Strip(TagTypes.Ape, false) && success); Mode = FileAccessMode.Closed; if(!success) throw new TagLibException(TagLibError.MpegCouldNotWriteTags); }
public override void Save() { if (IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; // Update ID3v2 tag long id3v2_location = FindId3v2(); int id3v2_size = 0; if (id3v2_location != -1) { Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) { TagLibDebugger.Debug("Mpc.File.Save() -- Id3v2 header is broken. Ignoring."); id3v2_location = -1; } else id3v2_size = (int)header.CompleteTagSize; } if (id3v2Tag != null) { if (id3v2_location >= 0) Insert(id3v2Tag.Render(), id3v2_location, id3v2_size); else Insert(id3v2Tag.Render(), 0, 0); } else if (id3v2_location >= 0) RemoveBlock(id3v2_location, id3v2_size); // Update ID3v1 tag long id3v1_location = FindId3v1(); if (id3v1Tag != null) { if (id3v1_location >= 0) Insert(id3v1Tag.Render(), id3v1_location, 128); else { Seek(0, System.IO.SeekOrigin.End); id3v1_location = Tell; WriteBlock(id3v1Tag.Render()); } } else if (id3v1_location >= 0) { RemoveBlock(id3v1_location, 128); id3v1_location = -1; } // Update APE tag long ape_location = FindApe(id3v1_location != -1); long ape_size = 0; if (ape_location >= 0) { Seek(ape_location); ape_size = (new ApeFooter(ReadBlock((int)ApeFooter.Size))).CompleteTagSize; ape_location = ape_location + ApeFooter.Size - ape_size; } if (apeTag != null) { if (ape_location >= 0) Insert(apeTag.Render(), ape_location, ape_size); else { if (id3v1_location >= 0) Insert(apeTag.Render(), id3v1_location, 0); else { Seek(0, System.IO.SeekOrigin.End); WriteBlock(apeTag.Render()); } } } else if (ape_location >= 0) RemoveBlock(ape_location, ape_size); Mode = FileAccessMode.Closed; }
public bool Strip(TagTypes types, bool freeMemory) { FileAccessMode original_mode = Mode; if (IsReadOnly) { TagLibDebugger.Debug("Mpeg.File.Strip() - Cannot strip tags from a read only file."); return(false); } try { Mode = FileAccessMode.Write; } catch (TagLibException) { TagLibDebugger.Debug("Mpeg.File.Strip() - Cannot strip tags from a read only file."); return(false); } if ((types & TagTypes.Id3v2) != 0) { long id3v2_location = FindId3v2(); if (id3v2_location >= 0) { Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) { TagLibDebugger.Debug("Mpc.File.Save() -- Id3v2 header is broken. Ignoring."); } else { RemoveBlock(id3v2_location, (int)header.CompleteTagSize); } } if (freeMemory) { id3v2_tag = null; } } long id3v1_location = FindId3v1(); if ((types & TagTypes.Id3v1) != 0) { if (id3v1_location >= 0) { Truncate(id3v1_location); id3v1_location = -1; } if (freeMemory) { id3v1_tag = null; } } if ((types & TagTypes.Ape) != 0) { long ape_location = FindApe(id3v1_location >= 0); if (ape_location != -1) { Seek(ape_location); int ape_size = (int)(new ApeFooter(ReadBlock((int)ApeFooter.Size))).CompleteTagSize; ape_location = ape_location + ApeFooter.Size - ape_size; RemoveBlock(ape_location, ape_size); } if (freeMemory) { ape_tag = null; } } tag.SetTags(id3v2_tag, ape_tag, id3v1_tag); Mode = original_mode; return(true); }
public void Save(TagTypes types, bool stripOthers) { if (types == TagTypes.None && stripOthers) { if (!Strip(TagTypes.AllTags)) { throw new TagLibException(TagLibError.MpegCouldNotStripTags); } return; } if (id3v2_tag == null && id3v1_tag == null && ape_tag == null) { if (stripOthers) { if (!Strip(TagTypes.AllTags)) { throw new TagLibException(TagLibError.MpegCouldNotStripTags); } } return; } if (IsReadOnly) { throw new ReadOnlyException(); } Mode = FileAccessMode.Write; // Create the tags if we've been asked to. Copy the values from the tag that // does exist into the new tag. if ((types & TagTypes.Id3v2) != 0 && id3v1_tag != null) { TagLib.Tag.Duplicate(id3v1_tag, FindTag(TagTypes.Id3v2, true), false); } if ((types & TagTypes.Id3v1) != 0 && id3v2_tag != null) { TagLib.Tag.Duplicate(id3v2_tag, FindTag(TagTypes.Id3v1, true), false); } bool success = true; if ((TagTypes.Id3v2 & types) != 0 && id3v2_tag != null && !id3v2_tag.IsEmpty) { long id3v2_location = FindId3v2(); int id3v2_size = 0; if (id3v2_location < 0) { id3v2_location = 0; } else { Seek(id3v2_location); Id3v2Header header = new Id3v2Header(ReadBlock((int)Id3v2Header.Size)); if (header.TagSize == 0) { TagLibDebugger.Debug("Mpc.File.Save() -- Id3v2 header is broken. Ignoring."); } else { id3v2_size = (int)header.CompleteTagSize; } } Insert(id3v2_tag.Render(), id3v2_location, id3v2_size); } else if (stripOthers) { success = Strip(TagTypes.Id3v2) && success; } if ((TagTypes.Id3v1 & types) != 0 && id3v1_tag != null && !id3v1_tag.IsEmpty) { long id3v1_location = FindId3v1(); if (id3v1_location < 0) { Seek(0, System.IO.SeekOrigin.End); } else { Seek(id3v1_location); } WriteBlock(id3v1_tag.Render()); } else if (stripOthers) { success = (Strip(TagTypes.Id3v1, false) && success); } // Dont save an APE-tag unless one has been created if ((TagTypes.Ape & types) != 0 && ape_tag != null && !ape_tag.IsEmpty) { long ape_location = FindApe(FindId3v1() >= 0); long ape_size = 0; if (ape_location < 0) { ape_location = Length; } else { Seek(ape_location); ape_size = (new ApeFooter(ReadBlock((int)ApeFooter.Size))).CompleteTagSize; ape_location = ape_location + ApeFooter.Size - ape_size; } Insert(ape_tag.Render(), ape_location, ape_size); } else if (stripOthers) { success = (Strip(TagTypes.Ape, false) && success); } Mode = FileAccessMode.Closed; if (!success) { throw new TagLibException(TagLibError.MpegCouldNotWriteTags); } }