예제 #1
0
            internal static FastRange Get(int start, int count)
            {
                var fr = _cachedRange ?? (_cachedRange = new FastRange());

                fr._start = start;
                fr._count = count;
                return(fr);
            }
예제 #2
0
        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;
            }
        }
예제 #3
0
        void InitTree(DataPacket packet)
        {
            bool sparse;
            int  total = 0;

            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;
            }
            else
            {
                // unordered
                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;
                    }
                }
            }
            // figure out the maximum bit size; if all are unused, don't do anything else
            if ((MaxBits = Lengths.Max()) > -1)
            {
                int   sortedCount     = 0;
                int[] codewordLengths = null;
                if (sparse && total >= Entries >> 2)
                {
                    codewordLengths = new int[Entries];
                    Array.Copy(Lengths, codewordLengths, Entries);

                    sparse = false;
                }

                // compute size of sorted tables
                if (sparse)
                {
                    sortedCount = total;
                }
                else
                {
                    sortedCount = 0;
                }

                int sortedEntries = sortedCount;

                int[] values    = null;
                int[] codewords = null;
                if (!sparse)
                {
                    codewords = new int[Entries];
                }
                else if (sortedEntries != 0)
                {
                    codewordLengths = new int[sortedEntries];
                    codewords       = new int[sortedEntries];
                    values          = new int[sortedEntries];
                }

                if (!ComputeCodewords(sparse, sortedEntries, codewords, codewordLengths, len: Lengths, n: Entries, values: values))
                {
                    throw new InvalidDataException();
                }

                var valueList = (IReadOnlyList <int>)values ?? FastRange.Get(0, codewords.Length);

                PrefixList = Huffman.BuildPrefixedLinkedList(valueList, codewordLengths ?? Lengths, codewords, out PrefixBitLength, out PrefixOverflowTree);
            }
        }