/// <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); ;
 }
Ejemplo n.º 2
0
 private void ParseBoxHeaders(long start, long end, List<BoxHeader> parents)
 {
     BoxHeader header;
     for (long i = start; i < end; i += header.TotalBoxSize)
     {
         header = new BoxHeader(this.file, i);
         if ((this.moov_tree == null) && (header.BoxType == BoxType.Moov))
         {
             List<BoxHeader> list = AddParent(parents, header);
             this.moov_tree = list.ToArray();
             this.ParseBoxHeaders(header.HeaderSize + i, header.TotalBoxSize + i, list);
         }
         else if (((header.BoxType == BoxType.Mdia) || (header.BoxType == BoxType.Minf)) || ((header.BoxType == BoxType.Stbl) || (header.BoxType == BoxType.Trak)))
         {
             this.ParseBoxHeaders(header.HeaderSize + i, header.TotalBoxSize + i, AddParent(parents, header));
         }
         else if ((this.udta_tree == null) && (header.BoxType == BoxType.Udta))
         {
             this.udta_tree = AddParent(parents, header).ToArray();
         }
         else if (header.BoxType == BoxType.Mdat)
         {
             this.mdat_start = i;
             this.mdat_end = i + header.TotalBoxSize;
         }
         if (header.TotalBoxSize == 0)
         {
             break;
         }
     }
 }
Ejemplo n.º 3
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);
 }
 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);
 }
        /// <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);
        }
Ejemplo n.º 9
0
 private static List<BoxHeader> AddParent(List<BoxHeader> parents, BoxHeader current)
 {
     List<BoxHeader> list = new List<BoxHeader>();
     if (parents != null)
     {
         list.AddRange(parents);
     }
     list.Add(current);
     return list;
 }
Ejemplo n.º 10
0
 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();
 }
Ejemplo n.º 11
0
        /// <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 ();
        }
		/*
		/// <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);
			*/
		}
Ejemplo n.º 13
0
 public FileParser(TagLib.File file)
 {
     if (file == null)
     {
         throw new ArgumentNullException("file");
     }
     this.file = file;
     this.first_header = new BoxHeader(file, 0L);
     if (this.first_header.BoxType != "ftyp")
     {
         throw new CorruptFileException("File does not start with 'ftyp' box.");
     }
 }
 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);
 }
Ejemplo n.º 15
0
		/// <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 ();
		}
Ejemplo n.º 16
0
 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);
 }
        /// <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 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);
 }
Ejemplo n.º 19
0
        /// <summary>
        ///    Parses boxes for a specified range, looking for chunk
        ///    offset boxes.
        /// </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>
        private void ParseChunkOffsets(long start, long end)
        {
            BoxHeader header;

            for (long position = start; position < end;
                 position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);

                if (header.BoxType == BoxType.Moov)
                {
                    ParseChunkOffsets(
                        header.HeaderSize + position,
                        header.TotalBoxSize + position);
                }
                else if (header.BoxType == BoxType.Moov ||
                         header.BoxType == BoxType.Mdia ||
                         header.BoxType == BoxType.Minf ||
                         header.BoxType == BoxType.Stbl ||
                         header.BoxType == BoxType.Trak)
                {
                    ParseChunkOffsets(
                        header.HeaderSize + position,
                        header.TotalBoxSize + position);
                }
                else if (header.BoxType == BoxType.Stco ||
                         header.BoxType == BoxType.Co64)
                {
                    stco_boxes.Add(BoxFactory.CreateBox(
                                       file, header));
                }
                else if (header.BoxType == BoxType.Mdat)
                {
                    mdat_start = position;
                    mdat_end   = position + header.TotalBoxSize;
                }

                if (header.TotalBoxSize == 0)
                {
                    break;
                }
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        ///    Parses boxes for a specified range, looking for headers.
        /// </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="parents">
        ///    A <see cref="T:System.Collections.Generic.List`1" /> object containing all the parent
        ///    handlers that apply to the range.
        /// </param>
        void ParseBoxHeaders(long start, long end, List <BoxHeader> parents)
        {
            BoxHeader header;

            for (long position = start; position < end; position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);

                if (moov_tree == null && header.BoxType == BoxType.Moov)
                {
                    List <BoxHeader> new_parents = AddParent(parents, header);
                    moov_tree = new_parents.ToArray();
                    ParseBoxHeaders(header.HeaderSize + position, header.TotalBoxSize + position, new_parents);
                }
                else if (header.BoxType == BoxType.Mdia ||
                         header.BoxType == BoxType.Minf ||
                         header.BoxType == BoxType.Stbl ||
                         header.BoxType == BoxType.Trak)
                {
                    ParseBoxHeaders(header.HeaderSize + position, header.TotalBoxSize + position, AddParent(parents, header));
                }
                else if (udta_tree == null &&
                         header.BoxType == BoxType.Udta)
                {
                    // For compatibility, we still store the tree to the first udta
                    // block. The proper way to get this info is from the individual
                    // IsoUserDataBox.ParentTree member.
                    udta_tree = AddParent(parents, header).ToArray();
                }
                else if (header.BoxType == BoxType.Mdat)
                {
                    mdat_start = position;
                    mdat_end   = position + header.TotalBoxSize;
                }

                if (header.TotalBoxSize == 0)
                {
                    break;
                }
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        ///    Parses boxes for a specified range, looking for tags.
        /// </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="parents">
        ///    A <see cref="T:List" /> of <see cref="BoxHeader" /> parents.
        /// </param>
        void ParseTag(long start, long end, List <BoxHeader> parents)
        {
            BoxHeader header;

            for (long position = start; position < end; position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);

                if (header.BoxType == BoxType.Moov)
                {
                    ParseTag(header.HeaderSize + position, header.TotalBoxSize + position, AddParent(parents, header));
                }
                else if (header.BoxType == BoxType.Mdia ||
                         header.BoxType == BoxType.Minf ||
                         header.BoxType == BoxType.Stbl ||
                         header.BoxType == BoxType.Trak)
                {
                    ParseTag(header.HeaderSize + position, header.TotalBoxSize + position, AddParent(parents, header));
                }
                else if (header.BoxType == BoxType.Udta)
                {
                    var udtaBox = BoxFactory.CreateBox(file, header) 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 (header.BoxType == BoxType.Mdat)
                {
                    mdat_start = position;
                    mdat_end   = position + header.TotalBoxSize;
                }

                if (header.TotalBoxSize == 0)
                {
                    break;
                }
            }
        }
Ejemplo n.º 22
0
        /// <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 ArgumentNullException(nameof(file));
            }

            file.Seek(DataPosition + 4);
            ByteVector box_data = file.ReadBlock(DataSize - 4);

            HandlerType = box_data.Mid(0, 4);

            int end = box_data.Find((byte)0, 16);

            if (end < 16)
            {
                end = box_data.Count;
            }
            Name = end > 16 ? box_data.ToString(StringType.UTF8, 16, end - 16) : string.Empty;
        }
Ejemplo n.º 23
0
        /// <summary>
        ///    Parses boxes for a specified range, looking for tags.
        /// </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>
        private void ParseTag(long start, long end)
        {
            BoxHeader header;

            for (long position = start; position < end;
                 position += header.TotalBoxSize)
            {
                header = new BoxHeader(file, position);

                if (header.BoxType == BoxType.Moov ||
                    header.BoxType == BoxType.Mdia ||
                    header.BoxType == BoxType.Minf ||
                    header.BoxType == BoxType.Stbl ||
                    header.BoxType == BoxType.Trak)
                {
                    ParseTag(header.HeaderSize + position,
                             header.TotalBoxSize + position);
                }
                else if (udta_box == null &&
                         header.BoxType == BoxType.Udta)
                {
                    udta_box = BoxFactory.CreateBox(file,
                                                    header) as IsoUserDataBox;
                }
                else if (header.BoxType == 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="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);
		}
Ejemplo n.º 25
0
        /// <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;
                }
                }
            }
        }
Ejemplo n.º 26
0
        /// <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;
            }
        }
Ejemplo n.º 27
0
		/// <summary>
		///    Parses boxes for a specified range, looking for chunk
		///    offset boxes.
		/// </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>
		private void ParseChunkOffsets (long start, long end)
		{
			BoxHeader header;
			
			for (long position = start; position < end;
				position += header.TotalBoxSize) {
				header = new BoxHeader (file, position);
				
				if (header.BoxType == BoxType.Moov) {
					ParseChunkOffsets (
						header.HeaderSize + position,
						header.TotalBoxSize + position);
				} else if (header.BoxType == BoxType.Moov ||
					header.BoxType == BoxType.Mdia ||
					header.BoxType == BoxType.Minf ||
					header.BoxType == BoxType.Stbl ||
					header.BoxType == BoxType.Trak) {
					ParseChunkOffsets (
						header.HeaderSize + position,
						header.TotalBoxSize + position);
				} else if (header.BoxType == BoxType.Stco ||
					header.BoxType == BoxType.Co64) {
					stco_boxes.Add (BoxFactory.CreateBox (
						file, header));
				} else if (header.BoxType == BoxType.Mdat) {
					mdat_start = position;
					mdat_end = position + header.TotalBoxSize;
				}
				
				if (header.TotalBoxSize == 0)
					break;
			}
		}
Ejemplo n.º 28
0
		/// <summary>
		///    Parses boxes for a specified range, looking for tags.
		/// </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>
		private void ParseTag (long start, long end,
		                              List<BoxHeader> parents)
		{
			BoxHeader header;
			
			for (long position = start; position < end;
				position += header.TotalBoxSize) {
				header = new BoxHeader (file, position);
				
				if (header.BoxType == BoxType.Moov) {
					ParseTag (header.HeaderSize + position,
						header.TotalBoxSize + position,
						AddParent (parents, header));
				} else if (header.BoxType == BoxType.Mdia ||
					header.BoxType == BoxType.Minf ||
					header.BoxType == BoxType.Stbl ||
					header.BoxType == BoxType.Trak) {
					ParseTag (header.HeaderSize + position,
						header.TotalBoxSize + position,
						AddParent (parents, header));
				} else if (header.BoxType == BoxType.Udta) {
					IsoUserDataBox udtaBox = BoxFactory.CreateBox (file,
					header) 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 (header.BoxType == BoxType.Mdat) {
					mdat_start = position;
					mdat_end = position + header.TotalBoxSize;
				}
				
				if (header.TotalBoxSize == 0)
					break;
			}
		}
Ejemplo n.º 29
0
 /// <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);
 }
Ejemplo n.º 30
0
 public override void Save()
 {
     if (udta_boxes.Count == 0)
     {
         IsoUserDataBox udtaBox = new IsoUserDataBox();
         udta_boxes.Add(udtaBox);
     }
     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;
         IsoUserDataBox udtaBox        = FindAppleTagUdta();
         if (null == udtaBox)
         {
             udtaBox = new IsoUserDataBox();
         }
         ByteVector tag_data = udtaBox.Render();
         if (udtaBox.ParentTree == null || udtaBox.ParentTree.Length == 0)
         {
             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);
             for (int i = parser.MoovTree.Length - 1; i >= 0; i--)
             {
                 size_change = parser.MoovTree[i].Overwrite(this, size_change);
             }
         }
         else
         {
             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);
             for (int i = udtaBox.ParentTree.Length - 2; i >= 0; i--)
             {
                 size_change = udtaBox.ParentTree[i].Overwrite(this, size_change);
             }
         }
         if (size_change != 0)
         {
             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;
     }
 }
Ejemplo n.º 31
0
        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));
        }
Ejemplo n.º 32
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
                {
                    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));
        }
Ejemplo n.º 33
0
 /// <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>
 /// <returns>
 ///    A newly created <see cref="Box" /> object.
 /// </returns>
 public static Box CreateBox(TagLib.File file, BoxHeader header)
 {
     return(CreateBox(file, header, null));
 }
Ejemplo n.º 34
0
 /// <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));
 }
Ejemplo n.º 35
0
        /// <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;
            }
        }
Ejemplo n.º 36
0
        /// <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);
        }
 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();
 }
Ejemplo n.º 38
0
        /// <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;
                }
            }
        }
Ejemplo n.º 39
0
		/// <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 ();
		}
Ejemplo n.º 40
0
        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));
        }
Ejemplo n.º 41
0
		/// <summary>
		///    Parses boxes for a specified range, looking for headers.
		/// </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="parents">
		///    A <see cref="T:System.Collections.Generic.List`1" /> object containing all the parent
		///    handlers that apply to the range.
		/// </param>
		private void ParseBoxHeaders (long start, long end,
		                              List<BoxHeader> parents)
		{
			BoxHeader header;
			
			for (long position = start; position < end;
				position += header.TotalBoxSize) {
				header = new BoxHeader (file, position);
				
				if (moov_tree == null &&
					header.BoxType == BoxType.Moov) {
					List<BoxHeader> new_parents = AddParent (
						parents, header);
					moov_tree = new_parents.ToArray ();
					ParseBoxHeaders (
						header.HeaderSize + position,
						header.TotalBoxSize + position,
						new_parents);
				} else if (header.BoxType == BoxType.Mdia ||
					header.BoxType == BoxType.Minf ||
					header.BoxType == BoxType.Stbl ||
					header.BoxType == BoxType.Trak) {
					ParseBoxHeaders (
						header.HeaderSize + position,
						header.TotalBoxSize + position,
						AddParent (parents, header));
				} else if (udta_tree == null &&
					header.BoxType == BoxType.Udta) {
					// For compatibility, we still store the tree to the first udta
					// block. The proper way to get this info is from the individual
					// IsoUserDataBox.ParentTree member.
					udta_tree = AddParent (parents,
						header).ToArray ();
				} else if (header.BoxType == BoxType.Mdat) {
					mdat_start = position;
					mdat_end = position + header.TotalBoxSize;
				}
				
				if (header.TotalBoxSize == 0)
					break;
			}
		}
Ejemplo n.º 42
0
 public AppleAdditionalInfoBox(BoxHeader header, TagLib.File file, IsoHandlerBox handler) :
     base(header, handler)
 {
     Data = LoadData(file);
 }
Ejemplo n.º 43
0
		/// <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;
			}
		}
Ejemplo n.º 44
0
 /// <summary>
 ///    Constructs and initializes a new instance of <see
 ///    cref="Box" /> with a specified header.
 /// </summary>
 /// <param name="header">
 ///    A <see cref="BoxHeader" /> object describing the new
 ///    instance.
 /// </param>
 protected Box(BoxHeader header) : this(header, null)
 {
 }
Ejemplo n.º 45
0
		/// <summary>
		///    Adds a parent to the end of an existing list of parents.
		/// </summary>
		/// <param name="parents">
		///    A <see cref="T:System.Collections.Generic.List`1" /> object containing an existing
		///    list of parents.
		/// </param>
		/// <param name="current">
		///    A <see cref="BoxHeader" /> object to add to the list.
		/// </param>
		/// <returns>
		///    A new <see cref="T:System.Collections.Generic.List`1" /> object containing the list
		///    of parents, including the added header.
		/// </returns>
		private static List<BoxHeader> AddParent (List<BoxHeader> parents,
		                                          BoxHeader current)
		{
			List<BoxHeader> boxes = new List<BoxHeader> ();
			if (parents != null)
				boxes.AddRange (parents);
			boxes.Add (current);
			return boxes;
		}
 /// <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);
 }
Ejemplo n.º 47
0
		/// <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);
		}
Ejemplo n.º 48
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)
					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);
		}
Ejemplo n.º 49
0
 /// <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);
 }
Ejemplo n.º 50
0
 /// <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;
 }
Ejemplo n.º 51
0
 /// <summary>
 ///    Constructs and initializes a new instance of <see
 ///    cref="FullBox" /> with a provided header, version, and
 ///    flags.
 /// </summary>
 /// <param name="header">
 ///    A <see cref="BoxHeader" /> object containing the header
 ///    to use for the new instance.
 /// </param>
 /// <param name="version">
 ///    A <see cref="byte" /> value containing the version of the
 ///    new instance.
 /// </param>
 /// <param name="flags">
 ///    A <see cref="byte" /> value containing the flags for the
 ///    new instance.
 /// </param>
 protected FullBox(BoxHeader header, byte version, uint flags)
     : base(header)
 {
     this.version = version;
     Flags        = flags;
 }
Ejemplo n.º 52
0
        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, file, handler)
 {
     this.Data = file.ReadBlock(base.DataSize);
 }
 /// <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);
 }
 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();
     }
 }
Ejemplo n.º 56
0
 /// <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;
 }