context: //
  // AviHeaderList.cs:
  //
  // Author:
  //   Brian Nickel (brian.nickel@gmail.com)
  //
  // Copyright (C) 2007 Brian Nickel
  //
  // This library is free software; you can redistribute it and/or modify
  // it  under the terms of the GNU Lesser General Public License version
  // 2.1 as published by the Free Software Foundation.
  //
  // This library is distributed in the hope that it will be useful, but
  // WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this library; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  // USA
  //
  
  using System;
  using System.Collections.Generic;
  using System.Runtime.InteropServices;
  
  namespace TagLib.Riff
  {
  	/// <summary>
  	///    This class provides support for reading an AVI header list to
  	///    extract stream information.
  	/// </summary>
  	public class AviHeaderList
  	{
  		/// <summary>
  		///    Contains the AVI header.
  		/// </summary>
  		AviHeader header;
  		
  		/// <summary>
  		///    Contains the AVI codec information.
  		/// </summary>
  		List<ICodec> codecs = new List<ICodec> ();
  
  		/// <summary>
  		///    Constructs and initializes a new instance of <see
  		///    cref="AviHeaderList" /> by reading the contents of a raw
  		///    RIFF list from a specified position in a <see
  		///    cref="TagLib.File"/>.
  		/// </summary>
  		/// <param name="file">
  		///    A <see cref="TagLib.File" /> object containing the file
  		///    from which the contents of the new instance is to be
  		///    read.
  		/// </param>
  		/// <param name="position">
  		///    A <see cref="long" /> value specify at what position to
  		///    read the list.
  		/// </param>
  		/// <param name="length">
  		///    A <see cref="int" /> value specifying the number of bytes
  		///    to read.
  		/// </param>
  		/// <exception cref="ArgumentNullException">
  		///    <paramref name="file" /> is <see langword="null" />.
  		/// </exception>
  		/// <exception cref="ArgumentOutOfRangeException">
  		///    <paramref name="position" /> is less than zero or greater
  		///    than the size of the file.
  		/// </exception>
  		/// <exception cref="CorruptFileException">
  		///    The list does not contain an AVI header or the AVI header
  		///    is the wrong length.
  		/// </exception>
  		public AviHeaderList (TagLib.File file, long position,
  		                      int length)
  		{
  			if (file == null)
  				throw new ArgumentNullException ("file");
  			
  			if (length < 0)
  				throw new ArgumentOutOfRangeException (
  					"length");
  			
  			if (position < 0 || position > file.Length - length)
  				throw new ArgumentOutOfRangeException (
  					"position");
  			
  			List list = new List (file, position, length);
  			
  			if (!list.ContainsKey ("avih"))
  				throw new CorruptFileException (
  					"Avi header not found.");
  			
  			ByteVector header_data = list ["avih"][0];
  			if (header_data.Count != 0x38)
  				throw new CorruptFileException (
  					"Invalid header length.");
  			
  			header = new AviHeader (header_data, 0);
  			
  			foreach (ByteVector list_data in list ["LIST"])
  				if (list_data.StartsWith ("strl"))
  					codecs.Add (AviStream
  						.ParseStreamList (list_data)
  						.Codec);
  		}
  		
  		/// <summary>
  		///    Gets the header for the current instance.
  		/// </summary>
  		/// <value>
  		///    A <see cref="AviHeader" /> object containing the header
  		///    for the current instance.
  		/// </value>
  		public AviHeader Header {
  			get {return header;}
  		}
  		
  		/// <summary>
  		///    Gets the codecs contained in the current instance.
  		/// </summary>
  		/// <value>
  		///    A <see cref="ICodec[]" /> containing the codecs contained
  		///    in the current instance.
  		/// </value>
  		public ICodec [] Codecs {
  			get {return codecs.ToArray ();}
  		}
  	}
  	
  	/// <summary>
  	///    This structure provides a representation of a Microsoft
  	///    AviMainHeader structure, minus the first 8 bytes.
  	/// </summary>
  	public struct AviHeader
  	{
  		/// <summary>
  		///    Contains the number of microseconds per frame.
  		/// </summary>
  		uint microseconds_per_frame;
  
  		/// <summary>
  		///    Contains the maximum number of bytes per second.
  		/// </summary>
  		uint max_bytes_per_second;
  
  		/// <summary>
  		///    Contains the flags.
  		/// </summary>
  		uint flags;
  
  		/// <summary>
  		///    Contains the total number of frames.
  		/// </summary>
  		uint total_frames;
  		
  		/// <summary>
  		///    Contains the number of initial frames.
  		/// </summary>
  		uint initial_frames;
  		
  		/// <summary>
  		///    Contains the number of streams.
  		/// </summary>
  		uint streams;
  		
  		/// <summary>
  		///    Contains the suggested buffer size.
  		/// </summary>
  		uint suggested_buffer_size;
  		
  		/// <summary>
  		///    Contains the video width.
  		/// </summary>
  		uint width;
  		
  		/// <summary>
  		///    Contains the video height.
  		/// </summary>
  		uint height;
  
  		/// <summary>
  		///    Constructs and initializes a new instance of <see
  		///    cref="AviHeader" /> by reading the raw structure from the
  		///    beginning of a <see cref="ByteVector" /> object.
  		/// </summary>
  		/// <param name="data">
  		///    A <see cref="ByteVector" /> object containing the raw
  		///    data structure.
  		/// </param>
  		/// <exception cref="ArgumentNullException">
  		///    <paramref name="data" /> is <see langword="null" />.
  		/// </exception>
  		/// <exception cref="CorruptFileException">
  		///    <paramref name="data" /> contains less than 40 bytes.
  		/// </exception>
  		[Obsolete("Use AviHeader(ByteVector,int)")]
  		public AviHeader (ByteVector data) : this (data, 0)
  		{
  		}
  
  		/// <summary>
  		///    Constructs and initializes a new instance of <see
  		///    cref="AviStreamHeader" /> by reading the raw structure
  		///    from a specified position in a <see cref="ByteVector" />
  		///    object.
  		/// </summary>
  		/// <param name="data">
  		///    A <see cref="ByteVector" /> object containing the raw
  		///    data structure.
  		/// </param>
  		/// <param name="offset">
  		///    A <see cref="int" /> value specifying the index in
  		///    <paramref name="data"/> at which the structure begins.
  		/// </param>
  		/// <exception cref="ArgumentNullException">
  		///    <paramref name="data" /> is <see langword="null" />.
  		/// </exception>
  		/// <exception cref="ArgumentOutOfRangeException">
  		///    <paramref name="offset" /> is less than zero.
  		/// </exception>
  		/// <exception cref="CorruptFileException">
  		///    <paramref name="data" /> contains less than 40 bytes at
  		///    <paramref name="offset" />.
  		/// </exception>
  		public AviHeader (ByteVector data, int offset)
  		{
  			if (data == null)
  				throw new ArgumentNullException ("data");
  			
  			if (offset < 0)
  				throw new ArgumentOutOfRangeException (
  					"offset");
  			
  			if (offset + 40 > data.Count)
  				throw new CorruptFileException (
  					"Expected 40 bytes.");
  			
  			microseconds_per_frame = data.Mid (offset,      4).ToUInt (false);
  			max_bytes_per_second   = data.Mid (offset +  4, 4).ToUInt (false);
  			flags                  = data.Mid (offset + 12, 4).ToUInt (false);
  			total_frames           = data.Mid (offset + 16, 4).ToUInt (false);
  			initial_frames         = data.Mid (offset + 20, 4).ToUInt (false);
  			streams                = data.Mid (offset + 24, 4).ToUInt (false);
  			suggested_buffer_size  = data.Mid (offset + 28, 4).ToUInt (false);
  			width                  = data.Mid (offset + 32, 4).ToUInt (false);
  			height                 = data.Mid (offset + 36, 4).ToUInt (false);
  		}
  		
  		/// <summary>
  		///    Gets the number of microseconds per frame.
  		/// </summary>
  		/// <value>
  		///    A <see cref="uint" /> value specifying number of
  		///    microseconds per frame.
  		/// </value>
  		public uint MicrosecondsPerFrame {
  			get {return microseconds_per_frame;}
  		}
  		
  		/// <summary>
  		///    Gets the maximum number of bytes per second.
  		/// </summary>
  		/// <value>
  		///    A <see cref="uint" /> value specifying maximum number of
  		///    bytes per second.
  		/// </value>
  		public uint MaxBytesPerSecond {
  			get {return max_bytes_per_second;}
  		}
  		
  		/// <summary>
  		///    Gets the file flags.
  		/// </summary>
  		/// <value>
  		///    A <see cref="uint" /> value specifying file flags.
  		/// </value>
  		public uint Flags {
  			get {return flags;}
  		}
  		
  		/// <summary>
  		///    Gets the number of frames in the file.
  		/// </summary>
  		/// <value>
  		///    A <see cref="uint" /> value specifying the number of
  		///    frames in the file.
  		/// </value>
  		public uint TotalFrames {
  			get {return total_frames;}
  		}
  		
  		/// <summary>
  		///    Gets how far ahead audio is from video.
  		/// </summary>
  		/// <value>
  		///    A <see cref="uint" /> value specifying how far ahead
  		///    audio is from video.
  		/// </value>
  		public uint InitialFrames {
  
gt: 			get {return initial_frames;}