public void Init(IPacket packet, IHuffman huffman) { // first, check the sync pattern var chkVal = packet.ReadBits(24); if (chkVal != 0x564342UL) { throw new InvalidDataException("Book header had invalid signature!"); } // get the counts Dimensions = (int)packet.ReadBits(16); Entries = (int)packet.ReadBits(24); // init the storage _lengths = new int[Entries]; InitTree(packet, huffman); InitLookupTable(packet); }
public void Init(IPacket packet, IHuffman huffman) { // first, check the sync pattern ulong bookSignature = packet.ReadBits(24); if (bookSignature != 0x564342UL) { throw new InvalidDataException("Book header has invalid signature."); } // get the counts Dimensions = (int)packet.ReadBits(16); Entries = (int)packet.ReadBits(24); // init the storage _lengths = new int[Entries]; InitTree(packet, huffman); InitLookupTable(packet); _prefixList = huffman.PrefixTree; _prefixBitLength = huffman.TableBits; _overflowList = huffman.OverflowList; }
private void InitTree(IPacket packet, IHuffman huffman) { bool sparse; int total = 0; int maxLen; if (packet.ReadBit()) { // ordered var len = (int)packet.ReadBits(5) + 1; for (var i = 0; i < Entries;) { var cnt = (int)packet.ReadBits(Utils.ilog(Entries - i)); while (--cnt >= 0) { _lengths[i++] = len; } ++len; } total = 0; sparse = false; maxLen = len; } else { // unordered maxLen = -1; sparse = packet.ReadBit(); for (var i = 0; i < Entries; i++) { if (!sparse || packet.ReadBit()) { _lengths[i] = (int)packet.ReadBits(5) + 1; ++total; } else { // mark the entry as unused _lengths[i] = -1; } if (_lengths[i] > maxLen) { maxLen = _lengths[i]; } } } // figure out the maximum bit size; if all are unused, don't do anything else if ((_maxBits = maxLen) > -1) { int[] codewordLengths = null; if (sparse && total >= Entries >> 2) { codewordLengths = new int[Entries]; Array.Copy(_lengths, codewordLengths, Entries); sparse = false; } int sortedCount; // compute size of sorted tables if (sparse) { sortedCount = total; } else { sortedCount = 0; } int[] values = null; int[] codewords = null; if (!sparse) { codewords = new int[Entries]; } else if (sortedCount != 0) { codewordLengths = new int[sortedCount]; codewords = new int[sortedCount]; values = new int[sortedCount]; } if (!ComputeCodewords(sparse, codewords, codewordLengths, _lengths, Entries, values)) { throw new InvalidDataException(); } var valueList = (IReadOnlyList <int>)values ?? FastRange.Get(0, codewords.Length); huffman.GenerateTable(valueList, codewordLengths ?? _lengths, codewords); _prefixList = huffman.PrefixTree; _prefixBitLength = huffman.TableBits; _overflowList = huffman.OverflowList; } }
private void InitTree(IPacket packet, IHuffman huffman) { int total = 0; int maxLength; bool sparse; if (packet.ReadBit()) { // ordered int length = (int)packet.ReadBits(5) + 1; for (int i = 0; i < Entries;) { int count = (int)packet.ReadBits(Utils.ILog(Entries - i)); while (--count >= 0) { _lengths[i++] = length; } length++; } total = 0; sparse = false; maxLength = length; } else { // unordered maxLength = -1; sparse = packet.ReadBit(); for (int i = 0; i < Entries; i++) { if (!sparse || packet.ReadBit()) { _lengths[i] = (int)packet.ReadBits(5) + 1; ++total; } else { // mark the entry as unused _lengths[i] = -1; } if (_lengths[i] > maxLength) { maxLength = _lengths[i]; } } } // figure out the maximum bit size; if all are unused, don't do anything else if ((_maxBits = maxLength) <= -1) { return; } int[]? codewordLengths = null; if (sparse && total >= Entries >> 2) { codewordLengths = new int[Entries]; Array.Copy(_lengths, codewordLengths, Entries); sparse = false; } // compute size of sorted tables int[]? values = null; int[] codewords; if (sparse) { codewordLengths = new int[total]; codewords = new int[total]; values = new int[total]; } else { codewords = new int[Entries]; } if (!ComputeCodewords(sparse, codewords, codewordLengths, _lengths, Entries, values)) { throw new InvalidDataException(); } var valueList = (IReadOnlyList <int>?)values ?? ThreadStaticRange.Get(0, codewords.Length); huffman.GenerateTable(valueList, codewordLengths ?? _lengths, codewords); }