/// <summary> /// Adds <paramref name="vlc"/> to this table and recursively creates /// new tables when needed. /// </summary> /// <param name="vlc">the VLC to add</param> public void AddVlc(Vlc vlc) { int n = Length - vlc.Length; if (n >= 0) { uint c = (vlc.Code << n) - Code; // Insert code into this table for (int i = 0; i < (1 << n); i++) { _lut[c + i] = vlc; } } else { uint c = (vlc.Code >> (-n)) - Code; VlcLut table = _lut[c] as VlcLut; // Follow chain of LUTs if (table == null) { _lut[c] = table = new VlcLut(Code + c, Length, Bits); } table.AddVlc(vlc); } }
/// <summary> /// Creates a VLC-table for the bit codes in <param name="data"/>. /// The <paramref name="data"/> is a list of bitcode and value pairs. /// Bitcode is encoded as a <c>string</c>, e.g. <c>"0010"</c>, /// and value is expected to be of type <typeparamref name="T"/>. /// </summary> /// <param name="data">array of bitcode, value pairs</param> /// <param name="defaultValue">the value returned for a value not found in the VLC-table</param> public VlcTable(object[,] data, T defaultValue) { if (data == null) { throw new ArgumentNullException("data"); } _defaultValue = defaultValue; _values = new Dictionary <Vlc, T>(); _lut = new VlcLut(0, 0, GetMaxBits(data)); // Add the codes to the table for (int i = 0; i < data.GetLength(0); i++) { string bitcode = data[i, 0] as string; if (bitcode == null || !(data[i, 1] is T)) { throw new ArgumentException(string.Format("Invalid data at index {0}", i), "data"); } Vlc vlc = new Vlc(Convert.ToUInt32(bitcode, 2), bitcode.Length); _values[vlc] = (T)data[i, 1]; _lut.AddVlc(vlc); } }
/// <summary> /// Retrieves the VLC code correspondig to a bit <paramref name="code"/>. /// </summary> /// <param name="code">the code of length <c>Bits</c></param> /// <returns>the VLC code, null if </c>code<c> is not in this table</returns> public Vlc GetVlc(uint code) { Vlc vlc = _lut[(code >> (_bits - Length)) - Code]; VlcLut table = (vlc as VlcLut); return((table == null) ? vlc : table.GetVlc(code)); }