/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleAdditionalInfoBox" /> with a provided header /// and handler by reading the contents from a specified /// file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public AppleAdditionalInfoBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { // We do not care what is in this custom data section // see: https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap2/qtff2.html Data = file.ReadBlock(DataSize > 0 ? DataSize : 0); ; }
public UnknownBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } this.data = base.LoadData(file); }
public AppleItemListBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } this.children = base.LoadChildren(file); }
/* * /// <summary> * /// Contains the children of the box. * /// </summary> * private BoxList children; */ #endregion #region Constructors /// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoVisualSampleEntry" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoVisualSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { file.Seek(base.DataPosition + 16); width = file.ReadBlock(2).ToUShort(); height = file.ReadBlock(2).ToUShort(); }
/// <summary> /// Creates a box by reading it from a file given its /// position in the file, 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="position"> /// A <see cref="long" /> value specifying at what seek /// position in <paramref name="file" /> to start reading. /// </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> internal static Box CreateBox(TagLib.File file, long position, BoxHeader parent, IsoHandlerBox handler, int index) { BoxHeader header = new BoxHeader(file, position); return(CreateBox(file, header, parent, handler, index)); }
public UnknownBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } this.data = LoadData(file); }
public IsoSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(base.DataPosition + 6L); this.data_reference_index = file.ReadBlock(2).ToUShort(); }
public IsoChunkOffsetBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { ByteVector vector = file.ReadBlock(base.DataSize); this.offsets = new uint[vector.Mid(0, 4).ToUInt()]; for (int i = 0; i < this.offsets.Length; i++) { this.offsets[i] = vector.Mid(4 + (i * 4), 4).ToUInt(); } }
public IsoSampleDescriptionBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new ArgumentNullException("file"); } this.entry_count = file.ReadBlock(4).ToUInt(); this.children = base.LoadChildren(file); }
public AppleAnnotationBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } children = LoadChildren(file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="UnknownBox" /> with a provided header and handler /// by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public UnknownBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException(nameof(file)); } data = file.ReadBlock(DataSize > 0 ? DataSize : 0); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoSampleTableBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoSampleTableBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) throw new ArgumentNullException ("file"); children = LoadChildren (file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleItemListBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public AppleItemListBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException(nameof(file)); } Children = LoadChildren(file); }
public IsoSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(base.DataPosition + 6); data_reference_index = file.ReadBlock(2).ToUShort(); }
public IsoSampleDescriptionBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new ArgumentNullException("file"); } entry_count = file.ReadBlock(4).ToUInt(); children = LoadChildren(file); }
/// <summary> /// Parses boxes for a specified range, looking for tags and /// properties. /// </summary> /// <param name="start"> /// A <see cref="long" /> value specifying the seek position /// at which to start reading. /// </param> /// <param name="end"> /// A <see cref="long" /> value specifying the seek position /// at which to stop reading. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object that applied to the /// range being searched. /// </param> /// <param name="parents"> /// A <see cref="T:List" /> of <see cref="BoxHeader" /> parents. /// </param> void ParseTagAndProperties(long start, long end, IsoHandlerBox handler, List <BoxHeader> parents) { BoxHeader header; for (long position = start; position < end; position += header.TotalBoxSize) { header = new BoxHeader(file, position); ByteVector type = header.BoxType; if (type == BoxType.Moov) { ParseTagAndProperties(header.HeaderSize + position, header.TotalBoxSize + position, handler, AddParent(parents, header)); } else if (type == BoxType.Mdia || type == BoxType.Minf || type == BoxType.Stbl || type == BoxType.Trak) { ParseTagAndProperties(header.HeaderSize + position, header.TotalBoxSize + position, handler, AddParent(parents, header)); } else if (type == BoxType.Stsd) { stsd_boxes.Add(BoxFactory.CreateBox(file, header, handler)); } else if (type == BoxType.Hdlr) { handler = BoxFactory.CreateBox(file, header, handler) as IsoHandlerBox; } else if (mvhd_box == null && type == BoxType.Mvhd) { mvhd_box = BoxFactory.CreateBox(file, header, handler) as IsoMovieHeaderBox; } else if (type == BoxType.Udta) { var udtaBox = BoxFactory.CreateBox(file, header, handler) as IsoUserDataBox; // Since we can have multiple udta boxes, save the parent for each one List <BoxHeader> new_parents = AddParent(parents, header); udtaBox.ParentTree = new_parents.ToArray(); udta_boxes.Add(udtaBox); } else if (type == BoxType.Mdat) { mdat_start = position; mdat_end = position + header.TotalBoxSize; } if (header.TotalBoxSize == 0) { break; } } }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoSampleTableBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoSampleTableBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException(nameof(file)); } children = LoadChildren(file); }
protected FullBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(base.DataPosition); ByteVector vector = file.ReadBlock(4); this.version = vector[0]; this.flags = vector.Mid(1, 3).ToUInt(); }
public IsoChunkLargeOffsetBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { ByteVector box_data = file.ReadBlock(DataSize); offsets = new ulong[(int)box_data.Mid(0, 4).ToUInt()]; for (int i = 0; i < offsets.Length; i++) { offsets[i] = box_data.Mid(4 + i * 8, 8).ToULong(); } }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="FullBox" /> with a provided header and handler by /// reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> protected FullBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) throw new ArgumentNullException ("file"); file.Seek (base.DataPosition); ByteVector header_data = file.ReadBlock (4); version = header_data [0]; flags = header_data.Mid (1, 3).ToUInt (); }
protected FullBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(base.DataPosition); ByteVector header_data = file.ReadBlock(4); version = header_data[0]; flags = header_data.Mid(1, 3).ToUInt(); }
/* * /// <summary> * /// Contains the children of the box. * /// </summary> * private BoxList children; */ #endregion #region Constructors /// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoVisualSampleEntry" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoVisualSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { file.Seek(base.DataPosition + 16); width = file.ReadBlock(2).ToUShort(); height = file.ReadBlock(2).ToUShort(); /* * TODO: What are the children anyway? * children = LoadChildren (file); */ }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoChunkOffsetBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> public IsoChunkOffsetBox (BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base (header, file, handler) { ByteVector box_data = file.ReadBlock (DataSize); offsets = new uint [(int) box_data.Mid (0, 4).ToUInt ()]; for (int i = 0; i < offsets.Length; i ++) offsets [i] = box_data.Mid (4 + i * 4, 4).ToUInt (); }
public IsoAudioSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(base.DataPosition + 8L); this.channel_count = file.ReadBlock(2).ToUShort(); this.sample_size = file.ReadBlock(2).ToUShort(); file.Seek(base.DataPosition + 0x10L); this.sample_rate = file.ReadBlock(4).ToUInt(); this.children = base.LoadChildren(file); }
/* /// <summary> /// Contains the children of the box. /// </summary> private BoxList children; */ #endregion #region Constructors /// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoVisualSampleEntry" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoVisualSampleEntry (BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base (header, file, handler) { file.Seek (base.DataPosition + 16); width = file.ReadBlock (2).ToUShort (); height = file.ReadBlock (2).ToUShort (); /* TODO: What are the children anyway? children = LoadChildren (file); */ }
public IsoAudioSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(base.DataPosition + 8); channel_count = file.ReadBlock(2).ToUShort(); sample_size = file.ReadBlock(2).ToUShort(); file.Seek(base.DataPosition + 16); sample_rate = file.ReadBlock(4).ToUInt(); children = LoadChildren(file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoHandlerBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoHandlerBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) throw new System.ArgumentNullException ("file"); file.Seek (DataPosition + 4); ByteVector box_data = file.ReadBlock (DataSize - 4); handler_type = box_data.Mid (0, 4); int end = box_data.Find ((byte) 0, 16); if (end < 16) end = box_data.Count; name = box_data.ToString (StringType.UTF8, 16, end - 16); }
public IsoHandlerBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new ArgumentNullException("file"); } file.Seek(this.DataPosition + 4L); ByteVector vector = file.ReadBlock(base.DataSize - 4); this.handler_type = vector.Mid(0, 4); int count = vector.Find(0, 0x10); if (count < 0x10) { count = vector.Count; } this.name = vector.ToString(StringType.UTF8, 0x10, count - 0x10); }
public AppleElementaryStreamDescriptor(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { int offset = 0; ByteVector box_data = file.ReadBlock(DataSize); decoder_config = new ByteVector(); if (box_data[offset++] == 3) { if (ReadLength(box_data, ref offset) < 20) { throw new CorruptFileException("Insufficient data present."); } es_id = box_data.Mid(offset, 2).ToUShort(); offset += 2; stream_priority = box_data[offset++]; } else { es_id = box_data.Mid(offset, 2).ToUShort(); offset += 2; } if (box_data[offset++] != 4) { throw new CorruptFileException("Could not identify decoder configuration descriptor."); } if (ReadLength(box_data, ref offset) < 15) { throw new CorruptFileException("Could not read data. Too small."); } object_type_id = box_data[offset++]; stream_type = box_data[offset++]; buffer_size_db = box_data.Mid(offset, 3).ToUInt(); offset += 3; max_bitrate = box_data.Mid(offset, 4).ToUInt(); offset += 4; average_bitrate = box_data.Mid(offset, 4).ToUInt(); offset += 4; if (box_data[offset++] != 5) { throw new CorruptFileException("Could not identify decoder specific descriptor."); } uint length = ReadLength(box_data, ref offset); decoder_config = box_data.Mid(offset, (int)length); }
public AppleElementaryStreamDescriptor(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { int offset = 0; ByteVector data = file.ReadBlock(base.DataSize); this.decoder_config = new ByteVector(); if (data[offset++] == 3) { if (ReadLength(data, ref offset) < 20) { throw new CorruptFileException("Insufficient data present."); } this.es_id = data.Mid(offset, 2).ToUShort(); offset += 2; this.stream_priority = data[offset++]; } else { this.es_id = data.Mid(offset, 2).ToUShort(); offset += 2; } if (data[offset++] != 4) { throw new CorruptFileException("Could not identify decoder configuration descriptor."); } if (ReadLength(data, ref offset) < 15) { throw new CorruptFileException("Could not read data. Too small."); } this.object_type_id = data[offset++]; this.stream_type = data[offset++]; this.buffer_size_db = data.Mid(offset, 3).ToUInt(); offset += 3; this.max_bitrate = data.Mid(offset, 4).ToUInt(); offset += 4; this.average_bitrate = data.Mid(offset, 4).ToUInt(); offset += 4; if (data[offset++] != 5) { throw new CorruptFileException("Could not identify decoder specific descriptor."); } uint num2 = ReadLength(data, ref offset); this.decoder_config = data.Mid(offset, (int) num2); }
public IsoHandlerBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new System.ArgumentNullException("file"); } file.Seek(DataPosition + 4); ByteVector box_data = file.ReadBlock(DataSize - 4); handler_type = box_data.Mid(0, 4); int end = box_data.Find((byte)0, 16); if (end < 16) { end = box_data.Count; } name = box_data.ToString(StringType.UTF8, 16, end - 16); }
/// <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) return new IsoAudioSampleEntry (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) && header.DataSize >= 4) 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); }
/// <summary> /// Creates a box by reading it from a file given its header /// and handler. /// </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="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> public static Box CreateBox (TagLib.File file, BoxHeader header, IsoHandlerBox handler) { return CreateBox (file, header, BoxHeader.Empty, handler, -1); }
/// <summary> /// Creates a box by reading it from a file given its /// position in the file and handler. /// </summary> /// <param name="file"> /// A <see cref="TagLib.File" /> object containing the file /// to read from. /// </param> /// <param name="position"> /// A <see cref="long" /> value specifying at what seek /// position in <paramref name="file" /> to start reading. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> public static Box CreateBox (TagLib.File file, long position, IsoHandlerBox handler) { return CreateBox (file, position, BoxHeader.Empty, handler, -1); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleDataBox" /> with a provided header and handler /// by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public AppleDataBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { Data = LoadData(file); }
/// <summary> /// Parses boxes for a specified range, looking for tags and /// properties. /// </summary> /// <param name="start"> /// A <see cref="long" /> value specifying the seek position /// at which to start reading. /// </param> /// <param name="end"> /// A <see cref="long" /> value specifying the seek position /// at which to stop reading. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object that applied to the /// range being searched. /// </param> private void ParseTagAndProperties (long start, long end, IsoHandlerBox handler, List<BoxHeader> parents) { BoxHeader header; for (long position = start; position < end; position += header.TotalBoxSize) { header = new BoxHeader (file, position); ByteVector type = header.BoxType; if (type == BoxType.Moov) { ParseTagAndProperties (header.HeaderSize + position, header.TotalBoxSize + position, handler, AddParent (parents, header)); } else if (type == BoxType.Mdia || type == BoxType.Minf || type == BoxType.Stbl || type == BoxType.Trak) { ParseTagAndProperties ( header.HeaderSize + position, header.TotalBoxSize + position, handler, AddParent (parents, header)); } else if (type == BoxType.Stsd) { stsd_boxes.Add (BoxFactory.CreateBox ( file, header, handler)); } else if (type == BoxType.Hdlr) { handler = BoxFactory.CreateBox (file, header, handler) as IsoHandlerBox; } else if (mvhd_box == null && type == BoxType.Mvhd) { mvhd_box = BoxFactory.CreateBox (file, header, handler) as IsoMovieHeaderBox; } else if (type == BoxType.Udta) { IsoUserDataBox udtaBox = BoxFactory.CreateBox (file, header, handler) as IsoUserDataBox; // Since we can have multiple udta boxes, save the parent for each one List<BoxHeader> new_parents = AddParent ( parents, header); udtaBox.ParentTree = new_parents.ToArray (); udta_boxes.Add(udtaBox); } else if (type == BoxType.Mdat) { mdat_start = position; mdat_end = position + header.TotalBoxSize; } if (header.TotalBoxSize == 0) break; } }
public IsoVisualSampleEntry(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { file.Seek(base.DataPosition + 0x10L); this.width = file.ReadBlock(2).ToUShort(); this.height = file.ReadBlock(2).ToUShort(); }
public IsoMovieHeaderBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { if (file == null) { throw new ArgumentNullException("file"); } int bytes_remaining = DataSize; ByteVector data; if (Version == 1) { data = file.ReadBlock(Math.Min(28, bytes_remaining)); if (data.Count >= 8) { creation_time = data.Mid(0, 8).ToULong(); } if (data.Count >= 16) { modification_time = data.Mid(8, 8).ToULong(); } if (data.Count >= 20) { timescale = data.Mid(16, 4).ToUInt(); } if (data.Count >= 28) { duration = data.Mid(20, 8).ToULong(); } bytes_remaining -= 28; } else { data = file.ReadBlock(Math.Min(16, bytes_remaining)); if (data.Count >= 4) { creation_time = data.Mid(0, 4).ToUInt(); } if (data.Count >= 8) { modification_time = data.Mid(4, 4).ToUInt(); } if (data.Count >= 12) { timescale = data.Mid(8, 4).ToUInt(); } if (data.Count >= 16) { duration = data.Mid(12, 4).ToUInt(); } bytes_remaining -= 16; } data = file.ReadBlock(Math.Min(6, bytes_remaining)); if (data.Count >= 4) { rate = data.Mid(0, 4).ToUInt(); } if (data.Count >= 6) { volume = data.Mid(4, 2).ToUShort(); } file.Seek(file.Tell + 70); bytes_remaining -= 76; data = file.ReadBlock(Math.Min(4, bytes_remaining)); if (data.Count >= 4) { next_track_id = data.Mid(0, 4).ToUInt(); } }
public AppleAdditionalInfoBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { Data = LoadData(file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleDataBox" /> with a provided header and handler /// by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public AppleDataBox (BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base (header, file, handler) { Data = LoadData (file); }
private static Box CreateBox(TagLib.File file, BoxHeader header, BoxHeader parent, IsoHandlerBox handler, int index) { 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)); } return(new UnknownBox(header, file, handler)); } else { return(new IsoSampleEntry(header, file, handler)); } } 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 (parent.BoxType == BoxType.Ilst) { return(new AppleAnnotationBox(header, file, handler)); } return(new UnknownBox(header, file, handler)); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="Box" /> with a specified header and handler. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object describing the new /// instance. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance, or <see /// langref="null" /> if no handler applies. /// </param> protected Box(BoxHeader header, IsoHandlerBox handler) { this.header = header; this.data_position = header.Position + header.HeaderSize; this.handler = handler; }
public IsoFreeSpaceBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { this.padding = base.DataSize; }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoMetaBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> public IsoFreeSpaceBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { padding = DataSize; }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoMovieHeaderBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoMovieHeaderBox (BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base (header, file, handler) { if (file == null) throw new ArgumentNullException ("file"); int bytes_remaining = DataSize; ByteVector data; if (Version == 1) { // Read version one (large integers). data = file.ReadBlock (Math.Min (28, bytes_remaining)); if (data.Count >= 8) creation_time = data.Mid (0, 8).ToULong (); if (data.Count >= 16) modification_time = data.Mid (8, 8).ToULong (); if (data.Count >= 20) timescale = data.Mid (16, 4).ToUInt (); if (data.Count >= 28) duration = data.Mid (20, 8).ToULong (); bytes_remaining -= 28; } else { // Read version zero (normal integers). data = file.ReadBlock (Math.Min (16, bytes_remaining)); if (data.Count >= 4) creation_time = data.Mid (0, 4).ToUInt (); if (data.Count >= 8) modification_time = data.Mid (4, 4).ToUInt (); if (data.Count >= 12) timescale = data.Mid (8, 4).ToUInt (); if (data.Count >= 16) duration = data.Mid (12, 4).ToUInt (); bytes_remaining -= 16; } data = file.ReadBlock (Math.Min (6, bytes_remaining)); if (data.Count >= 4) rate = data.Mid (0, 4).ToUInt (); if (data.Count >= 6) volume = data.Mid (4, 2).ToUShort (); file.Seek (file.Tell + 70); bytes_remaining -= 76; data = file.ReadBlock (Math.Min (4, bytes_remaining)); if (data.Count >= 4) next_track_id = data.Mid (0, 4).ToUInt (); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleElementaryStreamDescriptor" /> with a provided /// header and handler by reading the contents from a /// specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> /// <exception cref="CorruptFileException"> /// Valid data could not be read. /// </exception> public AppleElementaryStreamDescriptor(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { int offset = 0; ByteVector box_data = file.ReadBlock(DataSize); decoder_config = new ByteVector(); // Elementary Stream Descriptor Tag if (box_data [offset++] == 3) { // We have a descriptor tag. Check that it's at // least 20 long. if (ReadLength(box_data, ref offset) < 20) { throw new CorruptFileException( "Insufficient data present."); } es_id = box_data.Mid(offset, 2).ToUShort(); offset += 2; stream_priority = box_data [offset++]; } else { // The tag wasn't found, so the next two byte // are the ID, and after that, business as // usual. es_id = box_data.Mid(offset, 2).ToUShort(); offset += 2; } // Verify that the next data is the Decoder // Configuration Descriptor Tag and escape if it won't // work out. if (box_data [offset++] != 4) { throw new CorruptFileException( "Could not identify decoder configuration descriptor."); } // Check that it's at least 15 long. if (ReadLength(box_data, ref offset) < 15) { throw new CorruptFileException( "Could not read data. Too small."); } // Read a lot of good info. object_type_id = box_data [offset++]; stream_type = box_data [offset++]; buffer_size_db = box_data.Mid(offset, 3).ToUInt(); offset += 3; max_bitrate = box_data.Mid(offset, 4).ToUInt(); offset += 4; average_bitrate = box_data.Mid(offset, 4).ToUInt(); offset += 4; // Verify that the next data is the Decoder Specific // Descriptor Tag and escape if it won't work out. if (box_data [offset++] != 5) { throw new CorruptFileException( "Could not identify decoder specific descriptor."); } // The rest of the info is decoder specific. uint length = ReadLength(box_data, ref offset); decoder_config = box_data.Mid(offset, (int)length); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleAdditionalInfoBox" /> with a provided header /// and handler by reading the contents from a specified /// file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public AppleAdditionalInfoBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, handler) { // We do not care what is in this custom data section // see: https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap2/qtff2.html Data = LoadData(file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="Box" /> with a specified header and handler. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object describing the new /// instance. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance, or <see /// langref="null" /> if no handler applies. /// </param> protected Box (BoxHeader header, IsoHandlerBox handler) { this.header = header; this.data_position = header.Position + header.HeaderSize; this.handler = handler; }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoMetaBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoMetaBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { children = LoadChildren(file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleAdditionalInfoBox" /> with a provided header /// and handler by reading the contents from a specified /// file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public AppleAdditionalInfoBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { Data = file.ReadBlock(DataSize); }
/// <summary> /// Creates a box by reading it from a file given its /// position in the file, 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="position"> /// A <see cref="long" /> value specifying at what seek /// position in <paramref name="file" /> to start reading. /// </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> internal static Box CreateBox (TagLib.File file, long position, BoxHeader parent, IsoHandlerBox handler, int index) { BoxHeader header = new BoxHeader (file, position); return CreateBox (file, header, parent, handler, index); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="IsoMetaBox" /> with a provided header and /// handler by reading the contents from a specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> public IsoMetaBox (BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base (header, file, handler) { children = LoadChildren (file); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleElementaryStreamDescriptor" /> with a provided /// header and handler by reading the contents from a /// specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> /// <exception cref="CorruptFileException"> /// Valid data could not be read. /// </exception> public AppleElementaryStreamDescriptor(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { /* ES_Descriptor Specifications * Section 7.2.6.5 http://ecee.colorado.edu/~ecen5653/ecen5653/papers/ISO%2014496-1%202004.PDF */ ByteVector box_data = file.ReadBlock(DataSize); decoder_config = new ByteVector(); int offset = 0; // Elementary Stream Descriptor Tag if ((DescriptorTag)box_data[offset++] != DescriptorTag.ES_DescrTag) { throw new CorruptFileException("Invalid Elementary Stream Descriptor, missing tag."); } // We have a descriptor tag. Check that the remainder of the tag is at least [Base (3 bytes) + DecoderConfigDescriptor (15 bytes) + SLConfigDescriptor (3 bytes) + OtherDescriptors] bytes long uint es_length = ReadLength(box_data, ref offset); uint min_es_length = 3 + 15 + 3; // Base minimum length if (es_length < min_es_length) { throw new CorruptFileException("Insufficient data present."); } es_id = box_data.Mid(offset, 2).ToUShort(); offset += 2; // Done with ES_ID stream_dependence_flag = ((byte)((box_data[offset] >> 7) & 0x1) == 0x1 ? true : false); // 1st bit URL_flag = ((byte)((box_data[offset] >> 6) & 0x1) == 0x1 ? true : false); // 2nd bit ocr_stream_flag = ((byte)((box_data[offset] >> 5) & 0x1) == 0x1 ? true : false); // 3rd bit stream_priority = (byte)(box_data[offset++] & 0x1F); // Last 5 bits and we're done with this byte if (stream_dependence_flag) { min_es_length += 2; // We need 2 more bytes if (es_length < min_es_length) { throw new CorruptFileException("Insufficient data present."); } dependsOn_ES_ID = box_data.Mid(offset, 2).ToUShort(); offset += 2; // Done with stream dependence } if (URL_flag) { min_es_length += 2; // We need 1 more byte if (es_length < min_es_length) { throw new CorruptFileException("Insufficient data present."); } URLlength = box_data[offset++]; // URL Length min_es_length += URLlength; // We need URLength more bytes if (es_length < min_es_length) { throw new CorruptFileException("Insufficient data present."); } URLstring = box_data.Mid(offset, URLlength).ToString(); // URL name offset += URLlength; // Done with URL name } if (ocr_stream_flag) { min_es_length += 2; // We need 2 more bytes if (es_length < min_es_length) { throw new CorruptFileException("Insufficient data present."); } OCR_ES_Id = box_data.Mid(offset, 2).ToUShort(); offset += 2; // Done with OCR } while (offset < DataSize) // Loop through all trailing Descriptors Tags { DescriptorTag tag = (DescriptorTag)box_data[offset++]; switch (tag) { case DescriptorTag.DecoderConfigDescrTag: // DecoderConfigDescriptor { // Check that the remainder of the tag is at least 13 bytes long (13 + DecoderSpecificInfo[] + profileLevelIndicationIndexDescriptor[]) if (ReadLength(box_data, ref offset) < 13) { throw new CorruptFileException("Could not read data. Too small."); } // Read a lot of good info. object_type_id = box_data[offset++]; stream_type = (byte)(box_data[offset] >> 2); // First 6 bits upStream = ((byte)((box_data[offset++] >> 1) & 0x1) == 0x1 ? true : false); // 7th bit and we're done with the stream bits buffer_size_db = box_data.Mid(offset, 3).ToUInt(); offset += 3; // Done with bufferSizeDB max_bitrate = box_data.Mid(offset, 4).ToUInt(); offset += 4; // Done with maxBitrate average_bitrate = box_data.Mid(offset, 4).ToUInt(); offset += 4; // Done with avgBitrate // If there's a DecoderSpecificInfo[] array at the end it'll pick it up in the while loop } break; case DescriptorTag.DecSpecificInfoTag: // DecoderSpecificInfo { // The rest of the info is decoder specific. uint length = ReadLength(box_data, ref offset); decoder_config = box_data.Mid(offset, (int)length); offset += (int)length; // We're done with the config } break; case DescriptorTag.SLConfigDescrTag: // SLConfigDescriptor { // The rest of the info is SL specific. uint length = ReadLength(box_data, ref offset); offset += (int)length; // Skip the rest of the descriptor as reported in the length so we can move onto the next one } break; case DescriptorTag.Forbidden_00: case DescriptorTag.Forbidden_FF: throw new CorruptFileException("Invalid Descriptor tag."); default: { /* TODO: Should we handle other optional descriptor tags? * ExtensionDescriptor extDescr[0 .. 255]; * LanguageDescriptor langDescr[0 .. 1]; * IPI_DescPointer ipiPtr[0 .. 1]; * IP_IdentificationDataSet ipIDS[0 .. 1]; * QoS_Descriptor qosDescr[0 .. 1]; */ uint length = ReadLength(box_data, ref offset); // Every descriptor starts with a length offset += (int)length; // Skip the rest of the descriptor as reported in the length so we can move onto the next one break; } } } }
/// <summary> /// Creates a box by reading it from a file given its /// position in the file and handler. /// </summary> /// <param name="file"> /// A <see cref="TagLib.File" /> object containing the file /// to read from. /// </param> /// <param name="position"> /// A <see cref="long" /> value specifying at what seek /// position in <paramref name="file" /> to start reading. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> public static Box CreateBox(TagLib.File file, long position, IsoHandlerBox handler) { return(CreateBox(file, position, BoxHeader.Empty, handler, -1)); }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="AppleElementaryStreamDescriptor" /> with a provided /// header and handler by reading the contents from a /// specified file. /// </summary> /// <param name="header"> /// A <see cref="BoxHeader" /> object containing the header /// to use for the new instance. /// </param> /// <param name="file"> /// A <see cref="TagLib.File" /> object to read the contents /// of the box from. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new instance. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is <see langword="null" />. /// </exception> /// <exception cref="CorruptFileException"> /// Valid data could not be read. /// </exception> public AppleElementaryStreamDescriptor (BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base (header, file, handler) { int offset = 0; ByteVector box_data = file.ReadBlock (DataSize); decoder_config = new ByteVector (); // Elementary Stream Descriptor Tag if (box_data [offset ++] == 3) { // We have a descriptor tag. Check that it's at // least 20 long. if (ReadLength (box_data, ref offset) < 20) throw new CorruptFileException ( "Insufficient data present."); es_id = box_data.Mid (offset, 2).ToUShort (); offset += 2; stream_priority = box_data [offset ++]; } else { // The tag wasn't found, so the next two byte // are the ID, and after that, business as // usual. es_id = box_data.Mid (offset, 2).ToUShort (); offset += 2; } // Verify that the next data is the Decoder // Configuration Descriptor Tag and escape if it won't // work out. if (box_data [offset ++] != 4) throw new CorruptFileException ( "Could not identify decoder configuration descriptor."); // Check that it's at least 15 long. if (ReadLength (box_data, ref offset) < 15) throw new CorruptFileException ( "Could not read data. Too small."); // Read a lot of good info. object_type_id = box_data [offset ++]; stream_type = box_data [offset ++]; buffer_size_db = box_data.Mid (offset, 3).ToUInt (); offset += 3; max_bitrate = box_data.Mid (offset, 4).ToUInt (); offset += 4; average_bitrate = box_data.Mid (offset, 4).ToUInt (); offset += 4; // Verify that the next data is the Decoder Specific // Descriptor Tag and escape if it won't work out. if (box_data [offset ++] != 5) throw new CorruptFileException ( "Could not identify decoder specific descriptor."); // The rest of the info is decoder specific. uint length = ReadLength (box_data, ref offset); decoder_config = box_data.Mid (offset, (int) length); }
/// <summary> /// Creates a box by reading it from a file given its header /// and handler. /// </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="handler"> /// A <see cref="IsoHandlerBox" /> object containing the /// handler that applies to the new box. /// </param> /// <returns> /// A newly created <see cref="Box" /> object. /// </returns> public static Box CreateBox(TagLib.File file, BoxHeader header, IsoHandlerBox handler) { return(CreateBox(file, header, BoxHeader.Empty, handler, -1)); }
public AppleAdditionalInfoBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { this.Data = file.ReadBlock(base.DataSize); }
/// <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 { 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 IsoMovieHeaderBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) : base(header, file, handler) { ByteVector vector; if (file == null) { throw new ArgumentNullException("file"); } int dataSize = base.DataSize; if (base.Version == 1) { vector = file.ReadBlock(Math.Min(0x1c, dataSize)); if (vector.Count >= 8) { this.creation_time = vector.Mid(0, 8).ToULong(); } if (vector.Count >= 0x10) { this.modification_time = vector.Mid(8, 8).ToULong(); } if (vector.Count >= 20) { this.timescale = vector.Mid(0x10, 4).ToUInt(); } if (vector.Count >= 0x1c) { this.duration = vector.Mid(20, 8).ToULong(); } dataSize -= 0x1c; } else { vector = file.ReadBlock(Math.Min(0x10, dataSize)); if (vector.Count >= 4) { this.creation_time = vector.Mid(0, 4).ToUInt(); } if (vector.Count >= 8) { this.modification_time = vector.Mid(4, 4).ToUInt(); } if (vector.Count >= 12) { this.timescale = vector.Mid(8, 4).ToUInt(); } if (vector.Count >= 0x10) { this.duration = vector.Mid(12, 4).ToUInt(); } dataSize -= 0x10; } vector = file.ReadBlock(Math.Min(6, dataSize)); if (vector.Count >= 4) { this.rate = vector.Mid(0, 4).ToUInt(); } if (vector.Count >= 6) { this.volume = vector.Mid(4, 2).ToUShort(); } file.Seek(file.Tell + 70L); dataSize -= 0x4c; vector = file.ReadBlock(Math.Min(4, dataSize)); if (vector.Count >= 4) { this.next_track_id = vector.Mid(0, 4).ToUInt(); } }
/// <summary> /// Parses boxes for a specified range, looking for tags and /// properties. /// </summary> /// <param name="start"> /// A <see cref="long" /> value specifying the seek position /// at which to start reading. /// </param> /// <param name="end"> /// A <see cref="long" /> value specifying the seek position /// at which to stop reading. /// </param> /// <param name="handler"> /// A <see cref="IsoHandlerBox" /> object that applied to the /// range being searched. /// </param> private void ParseTagAndProperties (long start, long end, IsoHandlerBox handler) { BoxHeader header; for (long position = start; position < end; position += header.TotalBoxSize) { header = new BoxHeader (file, position); ByteVector type = header.BoxType; if (type == BoxType.Moov || type == BoxType.Mdia || type == BoxType.Minf || type == BoxType.Stbl || type == BoxType.Trak) { ParseTagAndProperties ( header.HeaderSize + position, header.TotalBoxSize + position, handler); } else if (type == BoxType.Stsd) { stsd_boxes.Add (BoxFactory.CreateBox ( file, header, handler)); } else if (type == BoxType.Hdlr) { handler = BoxFactory.CreateBox (file, header, handler) as IsoHandlerBox; } else if (mvhd_box == null && type == BoxType.Mvhd) { mvhd_box = BoxFactory.CreateBox (file, header, handler) as IsoMovieHeaderBox; } else if (udta_box == null && type == BoxType.Udta) { udta_box = BoxFactory.CreateBox (file, header, handler) as IsoUserDataBox; } else if (type == BoxType.Mdat) { mdat_start = position; mdat_end = position + header.TotalBoxSize; } if (header.TotalBoxSize == 0) break; } }