| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- using System;
- using System.IO;
- namespace Ryujinx.HLE.Loaders.Compression
- {
- static class BackwardsLz
- {
- private class BackwardsReader
- {
- private Stream BaseStream;
- public BackwardsReader(Stream BaseStream)
- {
- this.BaseStream = BaseStream;
- }
- public byte ReadByte()
- {
- BaseStream.Seek(-1, SeekOrigin.Current);
- byte Value = (byte)BaseStream.ReadByte();
- BaseStream.Seek(-1, SeekOrigin.Current);
- return Value;
- }
- public short ReadInt16()
- {
- return (short)((ReadByte() << 8) | (ReadByte() << 0));
- }
- public int ReadInt32()
- {
- return ((ReadByte() << 24) |
- (ReadByte() << 16) |
- (ReadByte() << 8) |
- (ReadByte() << 0));
- }
- }
- public static byte[] Decompress(Stream Input, int DecompressedLength)
- {
- long End = Input.Position;
- BackwardsReader Reader = new BackwardsReader(Input);
- int AdditionalDecLength = Reader.ReadInt32();
- int StartOffset = Reader.ReadInt32();
- int CompressedLength = Reader.ReadInt32();
- Input.Seek(12 - StartOffset, SeekOrigin.Current);
- byte[] Dec = new byte[DecompressedLength];
- int DecompressedLengthUnpadded = CompressedLength + AdditionalDecLength;
- int DecompressionStart = DecompressedLength - DecompressedLengthUnpadded;
- int DecPos = Dec.Length;
- byte Mask = 0;
- byte Header = 0;
- while (DecPos > DecompressionStart)
- {
- if ((Mask >>= 1) == 0)
- {
- Header = Reader.ReadByte();
- Mask = 0x80;
- }
- if ((Header & Mask) == 0)
- {
- Dec[--DecPos] = Reader.ReadByte();
- }
- else
- {
- ushort Pair = (ushort)Reader.ReadInt16();
- int Length = (Pair >> 12) + 3;
- int Position = (Pair & 0xfff) + 3;
- DecPos -= Length;
- if (Length <= Position)
- {
- int SrcPos = DecPos + Position;
- Buffer.BlockCopy(Dec, SrcPos, Dec, DecPos, Length);
- }
- else
- {
- for (int Offset = 0; Offset < Length; Offset++)
- {
- Dec[DecPos + Offset] = Dec[DecPos + Position + Offset];
- }
- }
- }
- }
- return Dec;
- }
- }
- }
|