/// <summary> /// Creates a static Huffman tree for encoding/decoding based on a tree emitted from WriteTable. /// </summary> /// <param name="symbolReader">Delegate for reading symbols.</param> /// <param name="valueReader">Delegate for reading unsigned integers.</param> public StaticHuffman(ReadSymbolDelegate <TSymbolType> symbolReader, ReadUInt32Delegate valueReader) { SymbolCount = valueReader(); _entries = new Entry[2 * SymbolCount - 1]; _map = new Dictionary <TSymbolType, SymbolInfo>((int)SymbolCount); for (uint i = 0; i < SymbolCount; ++i) { var symbol = symbolReader(); _entries[i].Symbol = symbol; SymbolInfo info; info.Index = i; info.Bits = null; _map[symbol] = info; } for (var i = SymbolCount; i < _entries.Length; ++i) { _entries[i].ChildIndex = new uint[2]; _entries[i].ChildIndex[0] = valueReader(); _entries[i].ChildIndex[1] = valueReader(); } ComputeParents(); Height = GetHeight(); Validate(); }
/// <summary> /// Retrieves a symbol. If the bit sequence from <paramref name="bitReader" /> /// identifies a symbol literal, <paramref name="symbolReader" /> is called. /// </summary> public TSymbolType GetSymbol(ReadBitDelegate bitReader, ReadSymbolDelegate <TSymbolType> symbolReader) { var result = GetSymbolInternal(bitReader); if (result.IsValid) { UpdateSymbolInternal(result, 1); UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(result.Symbol, false)); return(result.Symbol); } result = symbolReader(); UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(result.Symbol, true)); UpdateSymbolInternal(result, 1); return(result.Symbol); }