Пример #1
0
        private void ReadMode0x81(Stream input, Stream output)
        {
            using (var br = new BitReader(input, 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 dispIndexMapping = new Tree();
                dispIndexMapping.Build(br, 5);

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

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

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

                        var length   = output.Length - iVar4;
                        var position = 0;
                        do
                        {
                            length--;

                            output.Position = position;
                            var byte1 = output.ReadByte();

                            output.Position = position + iVar4;
                            var byte2 = output.ReadByte();

                            output.Position--;
                            output.WriteByte((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 dispIndex = dispIndexMapping.ReadValue(br);

                        var displacement = _dispRanges[dispIndex];
                        if (_dispBitReads[dispIndex] != 0)
                        {
                            displacement += br.ReadBits <int>(_dispBitReads[dispIndex]);
                        }

                        if (counter == 0)
                        {
                            continue;
                        }

                        var bufferIndex = _windowBufferOffset + _windowBuffer.Length - displacement;
                        for (int i = 0; i < counter; i++)
                        {
                            var next = _windowBuffer[bufferIndex++ % _windowBuffer.Length];
                            output.WriteByte(next);
                            _windowBuffer[_windowBufferOffset] = next;
                            _windowBufferOffset = (_windowBufferOffset + 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.WriteByte(rawValue);
                            _windowBuffer[_windowBufferOffset] = rawValue;
                            _windowBufferOffset = (_windowBufferOffset + 1) % _windowBuffer.Length;
                        }
                    }
                }
            }
        }
Пример #2
0
            public void Build(BitReader br, int valueBitCount)
            {
                _root = new Node();

                ReadNode(br, _root, valueBitCount);
            }