Beispiel #1
0
        private void ReadNode(BitReader br, Node node, int valueBitCount)
        {
            var flag = br.ReadBit();

            if (flag != 0)
            {
                node.Children[0] = new Node();
                ReadNode(br, node.Children[0], valueBitCount);

                node.Children[1] = new Node();
                ReadNode(br, node.Children[1], valueBitCount);
            }
            else
            {
                node.Value = br.ReadBits <int>(valueBitCount);
            }
        }
Beispiel #2
0
        public static byte[] Decompress(byte[] data, byte[] prev = null)
        {
            var output         = new List <byte>();
            var outputPosition = 0;

            if (prev != null)
            {
                output         = new List <byte>(prev);
                outputPosition = prev.Length;
            }

            using (var br = new BitReader(new MemoryStream(data), BitOrder.LSBFirst, 1, ByteOrder.LittleEndian))
            {
                var initialByte = br.ReadBits <int>(8);

                // 3 init holders
                var rawValueMapping = new Tree();
                rawValueMapping.Build(br, 8);
                var indexValueMapping = new Tree();
                indexValueMapping.Build(br, 6);
                var displacementIndexMapping = new Tree();
                displacementIndexMapping.Build(br, 5);

                while (true)
                {
                    var index = indexValueMapping.ReadValue(br);

                    if (index == 0)
                    {
                        // Finish decompression
                        if (initialByte < 3)
                        {
                            break;
                        }

                        var outputLength = output.Count - outputPosition;
                        var iVar4        = initialByte - 2;
                        if (outputLength <= iVar4)
                        {
                            break;
                        }

                        var length   = outputLength - iVar4;
                        var position = 0;
                        do
                        {
                            length--;

                            var byte1 = output[outputPosition + position];
                            var byte2 = output[outputPosition + iVar4 + position];

                            output[outputPosition + iVar4 + position] = (byte)(byte1 + byte2);

                            position++;
                        } while (length != 0);

                        break;
                    }

                    if (index < 0x20)
                    {
                        // Match reading
                        // Max displacement 0x8000; Min displacement 1
                        // Max length 0x102; Min length 1
                        var counter = Counters[index];
                        if (CounterBitReads[index] != 0)
                        {
                            counter += br.ReadBits <int>(CounterBitReads[index]);
                        }

                        var displacementIndex = displacementIndexMapping.ReadValue(br);

                        var displacement = DisplacementRanges[displacementIndex];
                        if (DisplacementBitReads[displacementIndex] != 0)
                        {
                            displacement += br.ReadBits <int>(DisplacementBitReads[displacementIndex]);
                        }

                        if (counter == 0)
                        {
                            continue;
                        }

                        var bufferIndex = _windowBufferPosition + WindowBuffer.Length - displacement;
                        for (int i = 0; i < counter; i++)
                        {
                            var next = WindowBuffer[bufferIndex++ % WindowBuffer.Length];
                            output.Add(next);
                            WindowBuffer[_windowBufferPosition] = next;
                            _windowBufferPosition = (_windowBufferPosition + 1) % WindowBuffer.Length;
                        }
                    }
                    else
                    {
                        // Raw data reading
                        index -= 0x20;

                        var counter = Counters[index];
                        if (CounterBitReads[index] != 0)
                        {
                            counter += br.ReadBits <int>(CounterBitReads[index]);
                        }

                        if (counter == 0)
                        {
                            continue;
                        }

                        for (int i = 0; i < counter; i++)
                        {
                            var rawValue = (byte)rawValueMapping.ReadValue(br);

                            output.Add(rawValue);
                            WindowBuffer[_windowBufferPosition] = rawValue;
                            _windowBufferPosition = (_windowBufferPosition + 1) % WindowBuffer.Length;
                        }
                    }
                }
            }

            return(output.ToArray());
        }