/* Compression types in order: * 10 = BZip2 * 8 = PKLib * 2 = ZLib * 1 = Huffman * 80 = IMA ADPCM Stereo * 40 = IMA ADPCM Mono */ private static byte[] DecompressMulti(byte[] Input, int OutputLength) { Stream sinput = new MemoryStream(Input); byte comptype = (byte)sinput.ReadByte(); #if WITH_BZIP // BZip2 if ((comptype & 0x10) != 0) { byte[] result = BZip2Decompress(sinput, OutputLength); comptype &= 0xEF; if (comptype == 0) return result; sinput = new MemoryStream(result); } #endif // PKLib if ((comptype & 8) != 0) { byte[] result = PKDecompress(sinput, OutputLength); comptype &= 0xF7; if (comptype == 0) return result; sinput = new MemoryStream(result); } #if WITH_ZLIB // ZLib if ((comptype & 2) != 0) { byte[] result = ZlibDecompress(sinput, OutputLength); comptype &= 0xFD; if (comptype == 0) return result; sinput = new MemoryStream(result); } #endif if ((comptype & 1) != 0) { byte[] result = MpqHuffman.Decompress(sinput); comptype &= 0xfe; if (comptype == 0) return result; sinput = new MemoryStream(result); } if ((comptype & 0x80) != 0) { byte[] result = MpqWavCompression.Decompress(sinput, 2); comptype &= 0x7f; if (comptype == 0) return result; sinput = new MemoryStream(result); } if ((comptype & 0x40) != 0) { byte[] result = MpqWavCompression.Decompress(sinput, 1); comptype &= 0xbf; if (comptype == 0) return result; sinput = new MemoryStream(result); } throw new MpqParserException(String.Format("Unhandled compression flags: 0x{0:X}", comptype)); }
/* Compression types in order: * 10 = BZip2 * 8 = PKLib * 2 = ZLib * 1 = Huffman * 80 = IMA ADPCM Stereo * 40 = IMA ADPCM Mono */ private static byte[] DecompressMulti(byte[] input, int outputLength) { Stream sinput = new MemoryStream(input); byte comptype = (byte)sinput.ReadByte(); // WC3 onward mosly use Zlib // Starcraft 1 mostly uses PKLib, plus types 41 and 81 for audio files switch (comptype) { case 1: // Huffman return(MpqHuffman.Decompress(sinput).ToArray()); case 2: // ZLib/Deflate #if WITH_ZLIB return(ZlibDecompress(sinput, outputLength)); #endif case 8: // PKLib/Impode return(PKDecompress(sinput, outputLength)); case 0x10: // BZip2 #if WITH_BZIP return(BZip2Decompress(sinput, outputLength)); #endif case 0x80: // IMA ADPCM Stereo return(MpqWavCompression.Decompress(sinput, 2)); case 0x40: // IMA ADPCM Mono return(MpqWavCompression.Decompress(sinput, 1)); case 0x12: // TODO: LZMA throw new MpqParserException("LZMA compression is not yet supported"); // Combos case 0x22: // TODO: sparse then zlib throw new MpqParserException("Sparse compression + Deflate compression is not yet supported"); case 0x30: // TODO: sparse then bzip2 throw new MpqParserException("Sparse compression + BZip2 compression is not yet supported"); case 0x41: sinput = MpqHuffman.Decompress(sinput); return(MpqWavCompression.Decompress(sinput, 1)); case 0x48: { byte[] result = PKDecompress(sinput, outputLength); return(MpqWavCompression.Decompress(new MemoryStream(result), 1)); } case 0x81: sinput = MpqHuffman.Decompress(sinput); return(MpqWavCompression.Decompress(sinput, 2)); case 0x88: { byte[] result = PKDecompress(sinput, outputLength); return(MpqWavCompression.Decompress(new MemoryStream(result), 2)); } default: throw new MpqParserException("Compression is not yet supported: 0x" + comptype.ToString("X")); } }