public MpegXingHeader(ByteVector data) { //frames = 0; //size = 0; //valid = false; Parse(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 Box GetChild(ByteVector type) { if (this.Children != null) { IEnumerator<Box> enumerator = this.Children.GetEnumerator(); try { while (enumerator.MoveNext()) { Box current = enumerator.Current; if (current.BoxType == type) { return current; } } } finally { if (enumerator == null) { } enumerator.Dispose(); } } return null; }
public BitmapInfoHeader(ByteVector data, int offset) { if (data == null) { throw new ArgumentNullException("data"); } if ((offset + 40) > data.Count) { throw new CorruptFileException("Expected 40 bytes."); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } this.size = data.Mid(offset, 4).ToUInt(false); this.width = data.Mid(offset + 4, 4).ToUInt(false); this.height = data.Mid(offset + 8, 4).ToUInt(false); this.planes = data.Mid(offset + 12, 2).ToUShort(false); this.bit_count = data.Mid(offset + 14, 2).ToUShort(false); this.compression_id = data.Mid(offset + 0x10, 4); this.size_of_image = data.Mid(offset + 20, 4).ToUInt(false); this.x_pixels_per_meter = data.Mid(offset + 0x18, 4).ToUInt(false); this.y_pixels_per_meter = data.Mid(offset + 0x1c, 4).ToUInt(false); this.colors_used = data.Mid(offset + 0x20, 4).ToUInt(false); this.colors_important = data.Mid(offset + 0x24, 4).ToUInt(false); }
protected internal Id3v2PrivateFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //this.owner = null; //this.data = null; //ParseFields(FieldData(data)); ParsePrivateFields(FieldData(data)); }
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; } }
// 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 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; }
protected void Parse (ByteVector data, byte version) { if (data == null) throw new ArgumentNullException ("data"); size = SynchData.ToUInt (data.Mid (0, 4)); }
////////////////////////////////////////////////////////////////////////// // public methods ////////////////////////////////////////////////////////////////////////// public AsfUnknownObject (AsfFile file, long position) : base (file, position) { if (file != null) { data = file.ReadBlock((int) (OriginalSize - 24)); } }
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); }
protected override void ParseFields(ByteVector data, byte version) { if (data.Count < 4) { throw new CorruptFileException("An object frame must contain at least 4 bytes."); } int offset = 0; this.encoding = (StringType) data[offset++]; int num2 = data.Find(ByteVector.TextDelimiter(StringType.Latin1), offset); if (num2 >= offset) { this.mime_type = data.ToString(StringType.Latin1, offset, num2 - offset); ByteVector pattern = ByteVector.TextDelimiter(this.encoding); offset = num2 + 1; num2 = data.Find(pattern, offset, pattern.Count); if (num2 >= offset) { this.file_name = data.ToString(this.encoding, offset, num2 - offset); offset = num2 + pattern.Count; num2 = data.Find(pattern, offset, pattern.Count); if (num2 >= offset) { this.description = data.ToString(this.encoding, offset, num2 - offset); offset = num2 + pattern.Count; data.RemoveRange(0, offset); this.data = data; } } } }
protected ByteVector FieldData(ByteVector frameData) { if (frameData != null) { uint headerSize = Id3v2FrameHeader.Size(header.Version); uint frameDataOffset = headerSize; uint frameDataLength = Size; if (header.Compression || header.DataLengthIndicator) { frameDataLength = frameData.Mid((int)headerSize, 4).ToUInt(); frameDataLength += 4; } // FIXME: Impliment compression and encrpytion. /* #if HAVE_ZLIB if(d->header->compression()) { ByteVector data(frameDataLength); uLongf uLongTmp = frameDataLength; ::uncompress((Bytef *) data.data(), (uLongf *) &uLongTmp, (Bytef *) frameData.data() + frameDataOffset, size()); return data; } else #endif */ return frameData.Mid((int)frameDataOffset, (int)frameDataLength); } else throw new ArgumentNullException("frameData"); }
protected void ParseHeader(ByteVector data) { if (header != null) header.SetData(data); else header = new Id3v2FrameHeader(data); }
public new ByteVector Render() { ByteVector output = new ByteVector(); output = _data; output.Insert(0, Header.Render()); return output; }
private ByteVector RenderTextIdentifierFields() { ByteVector vector = new ByteVector(); if (fieldList.Count > 0) { vector.Add((byte)textEncoding); bool first = true; foreach (string field in fieldList) { // Since the field text is null delimited, if this is not the // first element in the text, append the appropriate delimiter // for this encoding. if (!first) vector.Add(TextDelimiter(textEncoding)); first = false; vector.Add(ByteVector.FromString(field, textEncoding)); } } return vector; }
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; }
public AviStreamHeader(ByteVector data, int offset) { if (data == null) { throw new ArgumentNullException("data"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if ((offset + 0x38) > data.Count) { throw new CorruptFileException("Expected 56 bytes."); } this.type = data.Mid(offset, 4); this.handler = data.Mid(offset + 4, 4); this.flags = data.Mid(offset + 8, 4).ToUInt(false); this.priority = data.Mid(offset + 12, 4).ToUInt(false); this.initial_frames = data.Mid(offset + 0x10, 4).ToUInt(false); this.scale = data.Mid(offset + 20, 4).ToUInt(false); this.rate = data.Mid(offset + 0x18, 4).ToUInt(false); this.start = data.Mid(offset + 0x1c, 4).ToUInt(false); this.length = data.Mid(offset + 0x20, 4).ToUInt(false); this.suggested_buffer_size = data.Mid(offset + 0x24, 4).ToUInt(false); this.quality = data.Mid(offset + 40, 4).ToUInt(false); this.sample_size = data.Mid(offset + 0x2c, 4).ToUInt(false); this.left = data.Mid(offset + 0x30, 2).ToUShort(false); this.top = data.Mid(offset + 50, 2).ToUShort(false); this.right = data.Mid(offset + 0x34, 2).ToUShort(false); this.bottom = data.Mid(offset + 0x36, 2).ToUShort(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 override void ParseItem(ByteVector id, ByteVector data, int start, int length) { if (id == "strf") { base.Codec = new WaveFormatEx(data, start); } }
public Id3v2UnknownFrame(ByteVector data) : base(data) { //fieldData = null; //SetData(data); ParseHeader(data); ParseUnknownFields(data); }
protected override ByteVector Render(ByteVector topData) { ByteVector vector = new ByteVector(4) { topData }; return base.Render(vector); }
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; }
protected internal Id3v2UniqueFileIdentifierFrame(ByteVector data, Id3v2FrameHeader header) : base(header) { //owner = null; //identifier = null; //ParseFields(FieldData(data)); ParseUniqueFields(FieldData(data)); }
public bool ReadPage(Page page) { if (page == null) { throw new ArgumentNullException("page"); } ByteVector[] packets = page.Packets; for (int i = 0; i < packets.Length; i++) { if ((((byte) (page.Header.Flags & PageFlags.FirstPacketContinued)) == 0) && (this.previous_packet != null)) { if (this.ReadPacket(this.previous_packet)) { return true; } this.previous_packet = null; } ByteVector data = packets[i]; if (((i == 0) && (((byte) (page.Header.Flags & PageFlags.FirstPacketContinued)) != 0)) && (this.previous_packet != null)) { this.previous_packet.Add(data); data = this.previous_packet; } this.previous_packet = null; if (i == (packets.Length - 1)) { this.previous_packet = new ByteVector(data); } else if (this.ReadPacket(data)) { return true; } } return false; }
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); }
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; } }
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"); }
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 override void ParseItem(ByteVector id, ByteVector data, int start, int length) { if (id == "strf") { base.Codec = new BitmapInfoHeader(data, start); } }
/// <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 abstract void ParseFields(ByteVector data, byte version);
public AviHeader(ByteVector data) : this(data, 0) { }
/// <summary> /// Creates a box by reading it from a file given its header, /// parent header, handler, and index in its parent. /// </summary> /// <param name="file"> /// A <see cref="TagLib.File" /> object containing the file /// to read from. /// </param> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// of the box to create. /// </param> /// <param name="parent"> /// A <see cref="BoxHeader" /> object containing the header /// of the parent box. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <param name="index"> /// A <see cref="int" /> value containing the index of the /// new box in its parent. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> private static Box CreateBox(TagLib.File file, BoxHeader header, BoxHeader parent, IsoHandlerBox handler, int index) { // The first few children of an "stsd" are sample // entries. if (parent.BoxType == BoxType.Stsd && parent.Box is IsoSampleDescriptionBox && index < (parent.Box as IsoSampleDescriptionBox).EntryCount) { if (handler != null && handler.HandlerType == BoxType.Soun) { return(new IsoAudioSampleEntry(header, file, handler)); } else if (handler != null && handler.HandlerType == BoxType.Vide) { return(new IsoVisualSampleEntry(header, file, handler)); } else if (handler != null && handler.HandlerType == BoxType.Alis) { if (header.BoxType == BoxType.Text) { return(new TextBox(header, file, handler)); } else if (header.BoxType == BoxType.Url) { return(new UrlBox(header, file, handler)); } // This could be anything, so just parse it return(new UnknownBox(header, file, handler)); } else { return(new IsoSampleEntry(header, file, handler)); } } // Standard items... ByteVector type = header.BoxType; if (type == BoxType.Mvhd) { return(new IsoMovieHeaderBox(header, file, handler)); } else if (type == BoxType.Stbl) { return(new IsoSampleTableBox(header, file, handler)); } else if (type == BoxType.Stsd) { return(new IsoSampleDescriptionBox(header, file, handler)); } else if (type == BoxType.Stco) { return(new IsoChunkOffsetBox(header, file, handler)); } else if (type == BoxType.Co64) { return(new IsoChunkLargeOffsetBox(header, file, handler)); } else if (type == BoxType.Hdlr) { return(new IsoHandlerBox(header, file, handler)); } else if (type == BoxType.Udta) { return(new IsoUserDataBox(header, file, handler)); } else if (type == BoxType.Meta) { return(new IsoMetaBox(header, file, handler)); } else if (type == BoxType.Ilst) { return(new AppleItemListBox(header, file, handler)); } else if (type == BoxType.Data) { return(new AppleDataBox(header, file, handler)); } else if (type == BoxType.Esds) { return(new AppleElementaryStreamDescriptor( header, file, handler)); } else if (type == BoxType.Free || type == BoxType.Skip) { return(new IsoFreeSpaceBox(header, file, handler)); } else if (type == BoxType.Mean || type == BoxType.Name) { return(new AppleAdditionalInfoBox(header, file, handler)); } // If we still don't have a tag, and we're inside an // ItemListBox, load the box as an AnnotationBox // (Apple tag item). if (parent.BoxType == BoxType.Ilst) { return(new AppleAnnotationBox(header, file, handler)); } // Nothing good. Go generic. return(new UnknownBox(header, file, handler)); }
public static ByteVector TextDelimiter(StringType type) { return(ByteVector.TextDelimiter(type)); }
/// <summary> /// Extracts the field data from the raw data portion of an /// ID3v2 frame. /// </summary> /// <param name="frameData"> /// A <see cref="ByteVector" /> object containing fraw frame /// data. /// </param> /// <param name="offset"> /// A <see cref="int" /> value containing the index at which /// the data is contained. /// </param> /// <param name="version"> /// A <see cref="byte" /> value containing the ID3v2 version /// of the data. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// extracted field data. /// </returns> /// <remarks> /// This method is necessary for extracting extra data /// prepended to the frame such as the grouping ID. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="frameData" /> is <see langword="null" />. /// </exception> 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); } // FIXME: Implement encryption. if ((Flags & FrameFlags.Encryption) != 0) { throw new NotImplementedException(); } // FIXME: Implement compression. if ((Flags & FrameFlags.Compression) != 0) { throw new NotImplementedException(); } /* * if(d->header->compression()) { * ByteVector data(frameDataLength); * uLongf uLongTmp = frameDataLength; * ::uncompress((Bytef *) data.data(), * (uLongf *) &uLongTmp, * (Bytef *) frameData.data() + frameDataOffset, * size()); * return data; * } */ return(data); }
/// <summary> /// Reads an APP1 segment to find EXIF or XMP metadata. /// </summary> /// <param name="length"> /// The length of the segment that will be read. /// </param> private void ReadAPP1Segment(ushort length) { long position = Tell; ByteVector data = null; // for an Exif segment, the data block consists of 14 bytes of: // * 6 bytes Exif identifier string // * 2 bytes bigendian indication MM (or II) // * 2 bytes Tiff magic number (42) // * 4 bytes offset of the first IFD in this segment // // the last two points are alreay encoded according to // big- or littleendian int exif_header_length = 14; // could be an Exif segment if ((ImageTag.TagTypes & TagLib.TagTypes.TiffIFD) == 0x00 && length >= exif_header_length) { data = ReadBlock(exif_header_length); if (data.Count == exif_header_length && data.Mid(0, 6).ToString().Equals(EXIF_IDENTIFIER)) { bool is_bigendian = data.Mid(6, 2).ToString().Equals("MM"); ushort magic = data.Mid(8, 2).ToUShort(is_bigendian); if (magic != 42) { throw new Exception(String.Format("Invalid TIFF magic: {0}", magic)); } uint ifd_offset = data.Mid(10, 4).ToUInt(is_bigendian); var exif = new IFDTag(); var reader = new IFDReader(this, is_bigendian, exif.Structure, position + 6, ifd_offset, (uint)(length - 6)); reader.Read(); ImageTag.AddTag(exif); AddMetadataBlock(position - 4, length + 4); return; } } int xmp_header_length = XmpTag.XAP_NS.Length + 1; // could be an Xmp segment if ((ImageTag.TagTypes & TagLib.TagTypes.XMP) == 0x00 && length >= xmp_header_length) { // if already data is read for determining the Exif segment, // just read the remaining bytes. // NOTE: that (exif_header_length < xmp_header_length) holds if (data == null) { data = ReadBlock(xmp_header_length); } else { data.Add(ReadBlock(xmp_header_length - exif_header_length)); } if (data.ToString().Equals(XmpTag.XAP_NS + "\0")) { ByteVector xmp_data = ReadBlock(length - xmp_header_length); ImageTag.AddTag(new XmpTag(xmp_data.ToString(), this)); AddMetadataBlock(position - 4, length + 4); } } }
public GeneralEncapsulatedObjectFrame(ByteVector data, byte version) : base(data, version) { SetData(data, 0, version, true); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleDataBox" /> with specified data and flags. /// </summary> /// <param name="data"> /// A <see cref="ByteVector" /> object containing the data to /// store in the new instance. /// </param> /// <param name="flags"> /// A <see cref="uint" /> value containing flags to use for /// the new instance. /// </param> public AppleDataBox(ByteVector data, uint flags) : base("data", 0, flags) { Data = data; }
public void Mid() { Assert.AreEqual(ByteVector.FromString("KLMNOPQRSTUVWXYZ", StringType.UTF8), TestVector.Mid(10)); Assert.AreEqual(ByteVector.FromString("PQRSTU", StringType.UTF8), TestVector.Mid(15, 6)); }
public WaveFormatEx(ByteVector data) : this(data, 0) { }
public void SetText(params string[] text) { raw_data = null; Text = text; }
protected internal UserTextInformationFrame(ByteVector data, int offset, FrameHeader header, byte version) : base(data, offset, header, version) { }
public void SetText(StringCollection fields) { raw_data = null; Text = fields != null?fields.ToArray() : null; }
/// <summary> /// Renders the current instance, encoded in a specified /// ID3v2 version. /// </summary> /// <param name="version"> /// A <see cref="byte" /> value specifying the version of /// ID3v2 to use when encoding the current instance. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered version of the current instance. /// </returns> /// <exception cref="NotImplementedException"> /// The current instance uses some feature that cannot be /// implemented in the specified ID3v2 version, or uses a /// feature, such as encryption or compression, which is not /// yet implemented in the library. /// </exception> public virtual ByteVector Render(byte version) { // Remove flags that are not supported by older versions // of ID3v2. if (version < 4) { Flags &= ~(FrameFlags.DataLengthIndicator | FrameFlags.Unsynchronisation); } if (version < 3) { Flags &= ~(FrameFlags.Compression | FrameFlags.Encryption | FrameFlags.FileAlterPreservation | FrameFlags.GroupingIdentity | FrameFlags.ReadOnly | FrameFlags.TagAlterPreservation); } ByteVector field_data = RenderFields(version); // If we don't have any content, don't render anything. // This will cause the frame to not be rendered. if (field_data.Count == 0) { return(new ByteVector()); } ByteVector front_data = new ByteVector(); if ((Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator)) != 0) { front_data.Add(ByteVector.FromUInt((uint) field_data.Count)); } if ((Flags & FrameFlags.GroupingIdentity) != 0) { front_data.Add(group_id); } if ((Flags & FrameFlags.Encryption) != 0) { front_data.Add(encryption_id); } // FIXME: Implement compression. if ((Flags & FrameFlags.Compression) != 0) { throw new NotImplementedException( "Compression not yet supported"); } // FIXME: Implement encryption. if ((Flags & FrameFlags.Encryption) != 0) { throw new NotImplementedException( "Encryption not yet supported"); } if ((Flags & FrameFlags.Unsynchronisation) != 0) { SynchData.UnsynchByteVector(field_data); } if (front_data.Count > 0) { field_data.Insert(0, front_data); } header.FrameSize = (uint)field_data.Count; ByteVector header_data = header.Render(version); header_data.Add(field_data); return(header_data); }
protected internal TextInformationFrame(ByteVector data, int offset, FrameHeader header, byte version) : base(header) { SetData(data, offset, version, false); }
protected override ByteVector RenderFields(byte version) { if (raw_data != null && raw_version == version && raw_encoding == Tag.DefaultEncoding) { return(raw_data); } StringType encoding = CorrectEncoding(TextEncoding, version); ByteVector v = new ByteVector((byte)encoding); string[] text = text_fields; bool txxx = FrameId == FrameType.TXXX; if (version > 3 || txxx) { if (txxx) { if (text.Length == 0) { text = new string[] { null, null }; } else if (text.Length == 1) { text = new string[] { text[0], null }; } } for (int i = 0; i < text.Length; i++) { if (i != 0) { v.Add(ByteVector.TextDelimiter(encoding)); } if (text[i] != null) { v.Add(ByteVector.FromString(text[i], encoding)); } } } else if (FrameId == FrameType.TCON) { byte id; bool prev_value_indexed = true; StringBuilder data = new StringBuilder(); foreach (string s in text) { if (!prev_value_indexed) { data.Append("/").Append(s); continue; } if (prev_value_indexed = byte.TryParse(s, out id)) { data.AppendFormat(CultureInfo.InvariantCulture, "({0})", id); } else { data.Append(s); } } v.Add(ByteVector.FromString(data.ToString(), encoding)); } else { v.Add(ByteVector.FromString(string.Join("/", text), encoding)); } return(v); }
public TextInformationFrame(ByteVector data, byte version) : base(data, version) { SetData(data, 0, version, true); }
public UserTextInformationFrame(ByteVector data, byte version) : base(data, version) { }
protected void ParseRawData() { if (raw_data == null) { return; } ByteVector data = raw_data; raw_data = null; encoding = (StringType)data[0]; List <string> field_list = new List <string>(); ByteVector delim = ByteVector.TextDelimiter(encoding); if (raw_version > 3 || FrameId == FrameType.TXXX) { field_list.AddRange(data.ToStrings(encoding, 1)); } else if (data.Count > 1 && !data.Mid(1, delim.Count).Equals(delim)) { string value = data.ToString(encoding, 1, data.Count - 1); int null_index = value.IndexOf('\x00'); if (null_index >= 0) { value = value.Substring(0, null_index); } if (FrameId == FrameType.TCOM || FrameId == FrameType.TEXT || FrameId == FrameType.TOLY || FrameId == FrameType.TOPE || FrameId == FrameType.TPE1 || FrameId == FrameType.TPE2 || FrameId == FrameType.TPE3 || FrameId == FrameType.TPE4) { field_list.AddRange(value.Split('/')); } else if (FrameId == FrameType.TCON) { while (value.Length > 1 && value[0] == '(') { int closing = value.IndexOf(')'); if (closing < 0) { break; } string number = value.Substring(1, closing - 1); field_list.Add(number); value = value.Substring(closing + 1).TrimStart('/', ' '); string text = Genres.IndexToAudio(number); if (text != null && value.StartsWith(text)) { value = value.Substring(text.Length).TrimStart('/', ' '); } } if (value.Length > 0) { field_list.AddRange(value.Split(new char[] { '/' })); } } else { field_list.Add(value); } } 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(); }
public static TextInformationFrame Get(Tag tag, ByteVector ident) { return(Get(tag, ident, false)); }
protected override void ParseFields(ByteVector data, byte version) { raw_data = data; raw_version = version; raw_encoding = (StringType)data[0]; }
public TextInformationFrame(ByteVector ident) : this(ident, Id3v2.Tag.DefaultEncoding) { }
public static TextInformationFrame Get(Tag tag, ByteVector ident, bool create) { return(Get(tag, ident, Tag.DefaultEncoding, create)); }
/// <summary> /// Implements the <see cref="CodecProvider" /> delegate to /// provide support for recognizing a Vorbis stream from the /// header packet. /// </summary> /// <param name="packet"> /// A <see cref="ByteVector" /> object containing the stream /// header packet. /// </param> /// <returns> /// A <see cref="Codec"/> object containing a codec capable /// of parsing the stream of <see langref="null" /> if the /// stream is not a Vorbis stream. /// </returns> public static Codec FromPacket(ByteVector packet) { return((PacketType(packet) == 1) ? new Vorbis() : null); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="CommentsFrame" /> by reading its raw data in a /// specified ID3v2 version. /// </summary> /// <param name="data"> /// A <see cref="ByteVector" /> object starting with the raw /// representation of the new frame. /// </param> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// raw frame is encoded in. /// </param> public CommentsFrame(ByteVector data, byte version) : base(data, version) { SetData(data, 0, version, true); }
public TextInformationFrame(ByteVector ident, StringType encoding) : base(ident, 4) { this.encoding = encoding; }
protected internal PopularimeterFrame(ByteVector data, int offset, FrameHeader header, byte version) : base(header) { SetData(data, offset, version, false); }
/// <summary> /// Saves the changes made in the current instance to the /// file it represents. /// </summary> public override void Save() { if (udta_box == null) { udta_box = new IsoUserDataBox(); } // Try to get into write mode. Mode = File.AccessMode.Write; try { FileParser parser = new FileParser(this); parser.ParseBoxHeaders(); InvariantStartPosition = parser.MdatStartPosition; InvariantEndPosition = parser.MdatEndPosition; long size_change = 0; long write_position = 0; ByteVector tag_data = udta_box.Render(); // If we don't have a "udta" box to overwrite... if (parser.UdtaTree == null || parser.UdtaTree.Length == 0 || parser.UdtaTree [parser.UdtaTree.Length - 1 ].BoxType != BoxType.Udta) { // Stick the box at the end of the moov box. BoxHeader moov_header = parser.MoovTree [ parser.MoovTree.Length - 1]; size_change = tag_data.Count; write_position = moov_header.Position + moov_header.TotalBoxSize; Insert(tag_data, write_position, 0); // Overwrite the parent box sizes. for (int i = parser.MoovTree.Length - 1; i >= 0; i--) { size_change = parser.MoovTree [i ].Overwrite(this, size_change); } } else { // Overwrite the old box. BoxHeader udta_header = parser.UdtaTree [ parser.UdtaTree.Length - 1]; size_change = tag_data.Count - udta_header.TotalBoxSize; write_position = udta_header.Position; Insert(tag_data, write_position, udta_header.TotalBoxSize); // Overwrite the parent box sizes. for (int i = parser.UdtaTree.Length - 2; i >= 0; i--) { size_change = parser.UdtaTree [i ].Overwrite(this, size_change); } } // If we've had a size change, we may need to adjust // chunk offsets. if (size_change != 0) { // We may have moved the offset boxes, so we // need to reread. parser.ParseChunkOffsets(); InvariantStartPosition = parser.MdatStartPosition; InvariantEndPosition = parser.MdatEndPosition; foreach (Box box in parser.ChunkOffsetBoxes) { IsoChunkLargeOffsetBox co64 = box as IsoChunkLargeOffsetBox; if (co64 != null) { co64.Overwrite(this, size_change, write_position); continue; } IsoChunkOffsetBox stco = box as IsoChunkOffsetBox; if (stco != null) { stco.Overwrite(this, size_change, write_position); continue; } } } TagTypesOnDisk = TagTypes; } finally { Mode = File.AccessMode.Closed; } }
public PopularimeterFrame(ByteVector data, byte version) : base(data, version) { SetData(data, 0, version, true); }
/// <summary> /// Saves the changes made in the current instance to the /// file it represents. /// </summary> public override void Save() { if (udta_boxes.Count == 0) { IsoUserDataBox udtaBox = new IsoUserDataBox(); udta_boxes.Add(udtaBox); } // Try to get into write mode. Mode = File.AccessMode.Write; try { FileParser parser = new FileParser(this); parser.ParseBoxHeaders(); InvariantStartPosition = parser.MdatStartPosition; InvariantEndPosition = parser.MdatEndPosition; long size_change = 0; long write_position = 0; // To avoid rewriting udta blocks which might not have been modified, // the code here will work correctly if: // 1. There is a single udta for the entire file // - OR - // 2. There are multiple utdtas, but only 1 of them contains the Apple ILST box. // We should be OK in the vast majority of cases IsoUserDataBox udtaBox = FindAppleTagUdta(); if (null == udtaBox) { udtaBox = new IsoUserDataBox(); } ByteVector tag_data = udtaBox.Render(); // If we don't have a "udta" box to overwrite... if (udtaBox.ParentTree == null || udtaBox.ParentTree.Length == 0) { // Stick the box at the end of the moov box. BoxHeader moov_header = parser.MoovTree [ parser.MoovTree.Length - 1]; size_change = tag_data.Count; write_position = moov_header.Position + moov_header.TotalBoxSize; Insert(tag_data, write_position, 0); // Overwrite the parent box sizes. for (int i = parser.MoovTree.Length - 1; i >= 0; i--) { size_change = parser.MoovTree [i ].Overwrite(this, size_change); } } else { // Overwrite the old box. BoxHeader udta_header = udtaBox.ParentTree[udtaBox.ParentTree.Length - 1]; size_change = tag_data.Count - udta_header.TotalBoxSize; write_position = udta_header.Position; Insert(tag_data, write_position, udta_header.TotalBoxSize); // Overwrite the parent box sizes. for (int i = udtaBox.ParentTree.Length - 2; i >= 0; i--) { size_change = udtaBox.ParentTree [i ].Overwrite(this, size_change); } } // If we've had a size change, we may need to adjust // chunk offsets. if (size_change != 0) { // We may have moved the offset boxes, so we // need to reread. parser.ParseChunkOffsets(); InvariantStartPosition = parser.MdatStartPosition; InvariantEndPosition = parser.MdatEndPosition; foreach (Box box in parser.ChunkOffsetBoxes) { IsoChunkLargeOffsetBox co64 = box as IsoChunkLargeOffsetBox; if (co64 != null) { co64.Overwrite(this, size_change, write_position); continue; } IsoChunkOffsetBox stco = box as IsoChunkOffsetBox; if (stco != null) { stco.Overwrite(this, size_change, write_position); continue; } } } TagTypesOnDisk = TagTypes; } finally { Mode = File.AccessMode.Closed; } }