/* 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));
        }
Example #2
0
        /* 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"));
            }
        }