Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
        }
Esempio n. 3
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;
            }
        }
Esempio n. 4
0
        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);
        }