public PKLibDecompress(Stream Input) { mStream = new BitStream(Input); mCType = (CompressionType)Input.ReadByte(); if (mCType != CompressionType.Binary && mCType != CompressionType.Ascii) throw new MpqParserException("Invalid compression type: " + mCType); mDSizeBits = Input.ReadByte(); // This is 6 in test cases if (4 > mDSizeBits || mDSizeBits > 6) throw new MpqParserException("Invalid dictionary size: " + mDSizeBits); }
private static LinkedNode Decode(BitStream Input, LinkedNode Head) { LinkedNode node = Head; while(node.Child0 != null) { int bit = Input.ReadBits(1); if (bit == -1) throw new MpqParserException("Unexpected end of file"); node = bit == 0 ? node.Child0 : node.Child1; } return node; }
public static byte[] Decompress(Stream Data) { int comptype = Data.ReadByte(); if (comptype == 0) throw new NotImplementedException("Compression type 0 is not currently supported"); LinkedNode tail = BuildList(sPrime[comptype]); LinkedNode head = BuildTree(tail); MemoryStream outputstream = new MemoryStream(); BitStream bitstream = new BitStream(Data); int decoded; do { LinkedNode node = Decode(bitstream, head); decoded = node.DecompressedValue; switch(decoded) { case 256: break; case 257: int newvalue = bitstream.ReadBits(8); outputstream.WriteByte((byte)newvalue); tail = InsertNode(tail, newvalue); break; default: outputstream.WriteByte((byte)decoded); break; } } while (decoded != 256); return outputstream.ToArray(); }