示例#1
0
        public static BinaryReader Decompress(BinaryReader br, int size, int outsize)
        {
            if (input.Length < size)
            {
                input = new byte[size];
            }
            if (output.Length + 16 < outsize)
            {
                output = new byte[outsize + 16]; // Add 16 extra bytes to be able to detect uncompression overrun.
            }
            br.Read(input, 0, size);
            inf.Reset();
            inf.SetInput(input, 0, size);
            int decompressedSize = inf.Inflate(output);

            inf.Reset();

            ms.Position = 0;
            ms.Write(output, 0, outsize);
            ms.Position = 0;

            if (decompressedSize != outsize) // Check the size of the uncompressed data against what we expected
            {
                throw new Exception(String.Format("Unexpected Decompressed data size! CompressedSize={2:D} DecompressedSize={0:D} Expected Size={1:D}", decompressedSize, outsize, size));
            }

            return(compReader);
        }
示例#2
0
        public static byte[] GZip(byte[] input, int size, out int length)
        {
            if (size == 0)
            {
                var memory = new MemoryStream();
                deflater.Reset();
                using (var stream = new GZipOutputStream(memory, deflater, 4096, deflaterBuffer))
                {
                    stream.Write(input, 0, input.Length);
                }

                var array = memory.ToArray();
                length = array.Length;
                return(array);
            }
            else
            {
                if (size > decompressBuffer.Length)
                {
                    decompressBuffer = new byte[size];
                }

                inflater.Reset();
                using (var stream = new GZipInputStream(new MemoryStream(input), inflater, 4096, inflaterBuffer))
                {
                    stream.Read(decompressBuffer, 0, size);
                }

                length = size;
                return(decompressBuffer);
            }
        }
示例#3
0
        public static byte[] Decompress(byte[] input, int offset, int len)
        {
            byte[]   output     = new byte[1024];
            int      outputused = 0;
            Inflater inflater   = new Inflater();

            inflater.SetInput(input, offset, len);
            while (inflater.IsFinished == false)
            {
                if (inflater.IsNeedingInput)
                {
                    throw(new Exception("inflateData: input incomplete!"));
                }
                if (outputused == output.Length)
                {
                    byte[] newOutput = new byte[output.Length * 2];
                    Array.Copy(output, newOutput, output.Length);
                    output = newOutput;
                }
                try
                {
                    outputused += inflater.Inflate(output, outputused, output.Length - outputused);
                }
                catch (FormatException e)
                {
                    throw(new IOException(e.ToString()));
                }
            }
            inflater.Reset();
            byte[] realOutput = new byte[outputused];
            Array.Copy(output, realOutput, outputused);
            return(realOutput);
        }
            public void CopyTo(Stream output, Action <int> onProgress)
            {
                if (file.Flags.HasFlag(CABFlags.FileCompressed))
                {
                    var inf    = new Inflater(true);
                    var buffer = new byte[165535];
                    do
                    {
                        var bytesToExtract = currentVolume.ReadUInt16();
                        remainingInArchive -= 2;
                        toExtract          -= 2;
                        inf.SetInput(GetBytes(bytesToExtract));
                        toExtract -= bytesToExtract;
                        while (!inf.IsNeedingInput)
                        {
                            onProgress?.Invoke((int)(100 * output.Position / file.ExpandedSize));

                            var inflated = inf.Inflate(buffer);
                            output.Write(buffer, 0, inflated);
                        }

                        inf.Reset();
                    }while (toExtract > 0);
                }
                else
                {
                    do
                    {
                        onProgress?.Invoke((int)(100 * output.Position / file.ExpandedSize));

                        toExtract -= remainingInArchive;
                        output.Write(GetBytes(remainingInArchive), 0, (int)remainingInArchive);
                    }while (toExtract > 0);
                }
            }
示例#5
0
        public static byte[] Decompress(byte[] input, int offset, int len)
        {
            byte[]   sourceArray = new byte[0x400];
            int      num         = 0;
            Inflater inflater    = new Inflater();

            inflater.SetInput(input, offset, len);
            while (!inflater.IsFinished)
            {
                if (inflater.IsNeedingInput)
                {
                    throw new Exception("inflateData: input incomplete!");
                }
                if (num == sourceArray.Length)
                {
                    byte[] buffer2 = new byte[sourceArray.Length * 2];
                    Array.Copy(sourceArray, buffer2, sourceArray.Length);
                    sourceArray = buffer2;
                }
                try
                {
                    num += inflater.Inflate(sourceArray, num, sourceArray.Length - num);
                }
                catch (FormatException exception)
                {
                    throw new IOException(exception.ToString());
                }
            }
            inflater.Reset();
            byte[] destinationArray = new byte[num];
            Array.Copy(sourceArray, destinationArray, num);
            return(destinationArray);
        }
示例#6
0
            public void CopyTo(Stream dest)
            {
                if ((fileDes.Flags & FileCompressed) != 0)
                {
                    var inf    = new Inflater(true);
                    var buffer = new byte[165535];
                    do
                    {
                        var bytesToExtract = cabFile.ReadUInt16();
                        RemainingArchiveStream -= 2u;
                        RemainingFileStream    -= 2u;
                        inf.SetInput(GetBytes(bytesToExtract));
                        RemainingFileStream -= bytesToExtract;
                        while (!inf.IsNeedingInput)
                        {
                            var inflated = inf.Inflate(buffer);
                            dest.Write(buffer, 0, inflated);
                        }

                        inf.Reset();
                    }while (RemainingFileStream > 0);
                }
                else
                {
                    do
                    {
                        RemainingFileStream -= RemainingArchiveStream;
                        dest.Write(GetBytes(RemainingArchiveStream), 0, (int)RemainingArchiveStream);
                    }while (RemainingFileStream > 0);
                }
            }
示例#7
0
        protected static BinaryReader Decompress(BinaryReader br, int size, int outsize)
        {
            if (input.Length < size)
            {
                input = new byte[size];
            }
            if (output.Length < outsize)
            {
                output = new byte[outsize];
            }
            br.Read(input, 0, size);

            inf.SetInput(input, 0, size);
            try
            {
                inf.Inflate(output);
            }
            catch (SharpZipBaseException e)
            {
                //we ignore adler checksum mismatches, as I have a notion that they aren't always correctly
                // stored in the records.
                if (!e.Message.StartsWith("Adler"))
                {
                    throw e;
                }
            }
            inf.Reset();

            ms.Position = 0;
            ms.Write(output, 0, outsize);
            ms.Position = 0;

            return(compReader);
        }
示例#8
0
        /// <summary>
        /// Decompresses <paramref name="input"/> to <paramref name="output"/> with progress reports.
        /// </summary>
        /// <param name="input">The <see cref="Stream"/> with the data to decompress.</param>
        /// <param name="length">The length of the data in the <paramref name="input"/>.</param>
        /// <param name="output">The <see cref="Stream"/> to decompress to.</param>
        public void Decompress(Stream input,
                               uint length,
                               Stream output,
                               Action <ulong> progressReport,
                               long progressInterval = DefaultProgressInterval)
        {
            var raw = input.ReadBytes((int)length);
            var sw  = new Stopwatch();

            Inflater.Reset();
            Inflater.SetInput(raw, 0, raw.Length);
            sw.Start();

            int   count;
            ulong written = 0;

            byte[] buffer = new byte[BufferSize];
            while ((count = Inflater.Inflate(buffer)) > 0)
            {
                output.Write(buffer, 0, count);
                written += (ulong)count;

                if (sw.ElapsedMilliseconds >= progressInterval)
                {
                    progressReport?.Invoke(written);
                    sw.Restart();
                }
            }

            progressReport?.Invoke(written);
            sw.Stop();
        }
示例#9
0
文件: BSABrowser.cs 项目: vjmira/fomm
            internal void Extract(string path, bool UseFolderName, BinaryReader br, bool SkipName)
            {
                if (UseFolderName)
                {
                    path += "\\" + Folder + "\\" + FileName;
                }
                if (!Directory.Exists(Path.GetDirectoryName(path)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
                }
                var fs = File.Create(path);

                br.BaseStream.Position = Offset;
                if (SkipName)
                {
                    br.BaseStream.Position += br.ReadByte() + 1;
                }
                if (!Compressed)
                {
                    var bytes = new byte[Size];
                    br.Read(bytes, 0, (int)Size);
                    fs.Write(bytes, 0, (int)Size);
                }
                else
                {
                    var uncompressed = RealSize == 0 ? new byte[br.ReadUInt32()] : new byte[RealSize];
                    var compressed   = new byte[Size - 4];
                    br.Read(compressed, 0, (int)(Size - 4));
                    inf.Reset();
                    inf.SetInput(compressed);
                    inf.Inflate(uncompressed);
                    fs.Write(uncompressed, 0, uncompressed.Length);
                }
                fs.Close();
            }
示例#10
0
 /**
  * Release an inflater previously obtained from this cache.
  *
  * @param i
  *            the inflater to return. May be null, in which case this method
  *            does nothing.
  */
 public void release(Inflater i)
 {
     if (i != null)
     {
         i.Reset();
         releaseImpl(i);
     }
 }
示例#11
0
 /// <summary>Release an inflater previously obtained from this cache.</summary>
 /// <remarks>Release an inflater previously obtained from this cache.</remarks>
 /// <param name="i">
 /// the inflater to return. May be null, in which case this method
 /// does nothing.
 /// </param>
 public static void Release(Inflater i)
 {
     if (i != null)
     {
         i.Reset();
         if (ReleaseImpl(i))
         {
             i.Finish();
         }
     }
 }
示例#12
0
        private void SkipInflateFromInput(long sz)
        {
            Inflater inf = _inflater;

            try
            {
                byte[] dst = _objectData;
                int    n   = 0;
                int    p   = -1;
                while (!inf.IsFinished)
                {
                    if (inf.IsNeedingInput)
                    {
                        if (p >= 0)
                        {
                            _crc.Update(_buffer, p, _bAvail);
                            Use(_bAvail);
                        }
                        p = FillFromInput(1);
                        inf.SetInput(_buffer, p, _bAvail);
                    }

                    int free = dst.Length - n;
                    if (free < 8)
                    {
                        sz  -= n;
                        n    = 0;
                        free = dst.Length;
                    }
                    n += inf.Inflate(dst, n, free);
                }

                if (n != sz)
                {
                    throw new IOException("wrong decompressed length");
                }

                n = _bAvail - inf.RemainingInput;
                if (n > 0)
                {
                    _crc.Update(_buffer, p, n);
                    Use(n);
                }
            }
            catch (IOException e)
            {
                throw Corrupt(e);
            }
            finally
            {
                inf.Reset();
            }
        }
    private static Inflater GetInflater()
    {
        if (_inflater == null)
        {
            _inflater = new Inflater();
        }
        else
        {
            _inflater.Reset();
        }

        return(_inflater);
    }
示例#14
0
        /// <summary>
        /// Pump bytes into the supplied inflater as input.
        /// </summary>
        /// <param name="pack">The file the desired window is stored within.</param>
        /// <param name="position">Position within the file to read from.</param>
        /// <param name="dstbuf">
        /// Destination buffer the inflater should output decompressed
        /// data to.
        /// </param>
        /// <param name="dstoff">Current offset within <paramref name="dstbuf"/> to inflate into.</param>
        /// <returns>
        /// Updated <paramref name="dstoff"/> based on the number of bytes
        /// successfully inflated into <paramref name="dstbuf"/>.
        /// </returns>
        /// <remarks>
        /// this cursor does not match the provider or id and the proper
        /// window could not be acquired through the provider's cache.
        /// </remarks>
        public int Inflate(PackFile pack, long position, byte[] dstbuf, int dstoff)
        {
            if (_inflater == null)
            {
                _inflater = InflaterCache.Instance.get();
            }
            else
            {
                _inflater.Reset();
            }

            while (true)
            {
                Pin(pack, position);
                dstoff = _byteWindow.Inflate(position, dstbuf, dstoff, _inflater);
                if (_inflater.IsFinished)
                {
                    return(dstoff);
                }
                position = _byteWindow.End;
            }
        }
示例#15
0
        void ReadFooter()
        {
            var footer = new byte[8];

            // End of stream; reclaim all bytes from inf, read the final byte count, and reset the inflator
            var bytesRead = Inflater.TotalOut & 0xffffffff;

            InputBuffer.Available += Inflater.RemainingInput;
            Inflater.Reset();

            // Read footer from inputBuffer
            var needed = 8;

            while (needed > 0)
            {
                var count = InputBuffer.ReadClearTextBuffer(footer, 8 - needed, needed);
                if (count <= 0)
                {
                    throw new EndOfStreamException("EOS reading GZIP footer");
                }

                needed -= count; // Jewel Jan 16
            }

            // Calculate CRC
            var crcval = (footer[0] & 0xff) | ((footer[1] & 0xff) << 8) | ((footer[2] & 0xff) << 16) | (footer[3] << 24);

            if (crcval != (int)crc.Value)
            {
                throw new InvalidDataException("GZIP crc sum mismatch, theirs \"" + crcval + "\" and ours \"" + (int)crc.Value);
            }

            // NOTE The total here is the original total modulo 2 ^ 32.
            var total =
                (uint)footer[4] & 0xff |
                ((uint)footer[5] & 0xff) << 8 |
                    ((uint)footer[6] & 0xff) << 16 |
                    (uint)footer[7] << 24;

            if (bytesRead != total)
            {
                throw new InvalidDataException("Number of bytes mismatch in footer");
            }

            // Mark header read as false so if another header exists, we'll continue reading through the file
            readGZIPHeader = false;

            // Indicate that we succeeded on at least one block so we can exit gracefully if there is trailing garbage downstream
            completedLastBlock = true;
        }
示例#16
0
        public void ExtractFile(string filename, Stream output, Action <int> onProgress = null)
        {
            var file = files.FirstOrDefault(f => f.FileName == filename);

            if (file == null)
            {
                throw new FileNotFoundException(filename);
            }

            var folder = folders[file.FolderIndex];

            stream.Seek(folder.BlockOffset, SeekOrigin.Begin);

            var inflater          = new Inflater(true);
            var buffer            = new byte[4096];
            var decompressedBytes = 0;

            for (var i = 0; i < folder.BlockCount; i++)
            {
                if (onProgress != null)
                {
                    onProgress((int)(100 * output.Position / file.DecompressedLength));
                }

                // Ignore checksums
                stream.Position += 4;
                var blockLength = stream.ReadUInt16();
                stream.Position += 4;

                using (var batch = new MemoryStream(stream.ReadBytes(blockLength - 2)))
                    using (var inflaterStream = new InflaterInputStream(batch, inflater))
                    {
                        int n;
                        while ((n = inflaterStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            var offset = Math.Max(0, file.DecompressedOffset - decompressedBytes);
                            var count  = Math.Min(n - offset, file.DecompressedLength - decompressedBytes);
                            if (offset < n)
                            {
                                output.Write(buffer, (int)offset, (int)count);
                            }

                            decompressedBytes += n;
                        }
                    }

                inflater.Reset();
            }
        }
示例#17
0
            public override void Decompress(DataInput @in, int originalLength, int offset, int length, BytesRef bytes)
            {
                Debug.Assert(offset + length <= originalLength);
                if (length == 0)
                {
                    bytes.Length = 0;
                    return;
                }
                int compressedLength = @in.ReadVInt();

                if (compressedLength > Compressed.Length)
                {
                    Compressed = new byte[ArrayUtil.Oversize(compressedLength, 1)];
                }
                @in.ReadBytes(Compressed, 0, compressedLength);

                decompressor.Reset();
                decompressor.SetInput(Compressed, 0, compressedLength);

                bytes.Offset = bytes.Length = 0;
                while (true)
                {
                    int count;
                    try
                    {
                        int remaining = bytes.Bytes.Length - bytes.Length;
                        count = decompressor.Inflate((byte[])(Array)(bytes.Bytes), bytes.Length, remaining);
                    }
                    catch (System.FormatException e)
                    {
                        throw new System.IO.IOException("See inner", e);
                    }
                    bytes.Length += count;
                    if (decompressor.IsFinished)
                    {
                        break;
                    }
                    else
                    {
                        bytes.Bytes = ArrayUtil.Grow(bytes.Bytes);
                    }
                }
                if (bytes.Length != originalLength)
                {
                    throw new CorruptIndexException("Lengths mismatch: " + bytes.Length + " != " + originalLength + " (resource=" + @in + ")");
                }
                bytes.Offset = offset;
                bytes.Length = length;
            }
示例#18
0
        private void ReadFooter()
        {
            byte[] footer = new byte[8];

            buffer.available += inflater.input.availableBytes;
            inflater.Reset();

            int needed = 8;

            while (needed > 0)
            {
                int count = buffer.ReadClearTextBuffer(footer, 8 - needed, needed);
                needed -= count;
            }

            readHeader = false;
        }
示例#19
0
        private byte[] InflateFromInput(int size)
        {
            var      dst = new byte[size];
            Inflater inf = _inflater;

            try
            {
                int n = 0;
                int p = -1;
                while (!inf.IsFinished)
                {
                    if (inf.IsNeedingInput)
                    {
                        if (p >= 0)
                        {
                            _crc.Update(_buffer, p, _bAvail);
                            Use(_bAvail);
                        }
                        p = FillFromInput(1);
                        inf.SetInput(_buffer, p, _bAvail);
                    }

                    n += inf.Inflate(dst, n, dst.Length - n);
                }
                if (n != size)
                {
                    throw new IOException("Wrong decrompressed length");
                }
                n = _bAvail - inf.RemainingInput;
                if (n > 0)
                {
                    _crc.Update(_buffer, p, n);
                    Use(n);
                }
                return(dst);
            }
            catch (IOException e)
            {
                throw Corrupt(e);
            }
            finally
            {
                inf.Reset();
            }
        }
示例#20
0
 /// <summary>
 /// Resets everything, including the input buffer, regardless of whether the
 /// current gzip substream is finished.</p>
 /// </summary>
 public virtual void Reset()
 {
     lock (this)
     {
         // could optionally emit INFO message if state != GzipStateLabel.FINISHED
         inflater.Reset();
         state = BuiltInGzipDecompressor.GzipStateLabel.HeaderBasic;
         crc.Reset();
         userBufOff                  = userBufLen = 0;
         localBufOff                 = 0;
         headerBytesRead             = 0;
         trailerBytesRead            = 0;
         numExtraFieldBytesRemaining = -1;
         hasExtraField               = false;
         hasFilename                 = false;
         hasComment                  = false;
         hasHeaderCRC                = false;
     }
 }
示例#21
0
        protected override void Decode(IChannelHandlerContext ctx, IByteBuffer msg, List <object> output)
        {
            var uncompressedSize = msg.ReadVarInt32();

            if (uncompressedSize == 0)
            {
                var length = msg.ReadableBytes;
                if (length >= CompressionThreshold)
                {
                    throw new DecoderException("Badly compressed message");
                }

                msg.Retain();
                output.Add(msg);
                return;
            }

            if (uncompressedSize < CompressionThreshold)
            {
                throw new DecoderException("Badly compressed message (uncompressed size: " + uncompressedSize + ')');
            }
            if (uncompressedSize > 1 << 21)
            {
                throw new DecoderException("Badly compressed message (size over protocol limit: " + uncompressedSize + ')');
            }

            var inputBuffer = msg.ToArray(out var offset, out var count);

            _inflater.SetInput(inputBuffer, offset, count);

            var outputBuffer   = new byte[uncompressedSize];
            var processedBytes = _inflater.Inflate(outputBuffer);

            _inflater.Reset();

            if (uncompressedSize != processedBytes)
            {
                throw new DecoderException("Badly compressed message");
            }

            output.Add(Unpooled.WrappedBuffer(outputBuffer));
        }
示例#22
0
        public static BinaryReader Decompress(BinaryReader br, int size, int outsize)
        {
            if (input.Length < size)
            {
                input = new byte[size];
            }
            if (output.Length < outsize)
            {
                output = new byte[outsize];
            }
            br.Read(input, 0, size);
            inf.SetInput(input, 0, size);
            inf.Inflate(output);
            inf.Reset();

            ms.Position = 0;
            ms.Write(output, 0, outsize);
            ms.Position = 0;

            return(compReader);
        }
示例#23
0
        public void Decode(EndianBinaryReader reader, int dataLen, bool isCompress)
        {
#if REIGN_MSG_PROTOCOL_CLUSTER
            reader.ReadByte();
#endif
            _bytes  = reader.ReadBytes(32);
            command = Encoding.UTF8.GetString(_bytes);
            command = command.Trim('\0');

            requestId = reader.ReadInt32();

#if REIGN_MSG_PROTOCOL_CLUSTER
            bytes = reader.ReadBytes(dataLen - 37);
#else
            _bytes = reader.ReadBytes(dataLen - 36);
#endif
            if (isCompress)
            {
                try
                {
                    _output.Seek(0, SeekOrigin.End);
                    _inflater.SetInput(_bytes);
                    while (!_inflater.IsFinished)
                    {
                        _len = _inflater.Inflate(_buff);
                        _output.Write(_buff, 0, _len);
                    }
                    content = Encoding.UTF8.GetString(_output.ToArray());
                    _output.Seek(0, SeekOrigin.Begin);
                    _output.SetLength(0);
                    _inflater.Reset();
                } catch (Exception e) {
                    content = "decompress error:" + e.ToString();
                }
            }
            else
            {
                content = Encoding.UTF8.GetString(_bytes);
            }
        }
        public static (byte[] Data, long InputLength) Inflate(byte[] inputData)
        {
            var inflater = new Inflater();

            using (var inputStream = new MemoryStream(inputData))
                using (var ms = new MemoryStream())
                {
                    var inputBuffer  = new byte[4096];
                    var outputBuffer = new byte[4096];

                    while (inputStream.Position < inputData.Length)
                    {
                        var read = inputStream.Read(inputBuffer, 0, inputBuffer.Length);

                        inflater.SetInput(inputBuffer, 0, read);

                        while (!inflater.IsNeedingInput)
                        {
                            var written = inflater.Inflate(outputBuffer, 0, outputBuffer.Length);
                            if (written == 0)
                            {
                                break;
                            }

                            ms.Write(outputBuffer, 0, written);
                        }

                        if (inflater.IsFinished)
                        {
                            break;
                        }
                    }

                    var inputLength = inflater.TotalIn;

                    inflater.Reset();

                    return(ms.ToArray(), inputLength);
                }
        }
示例#25
0
        public static byte[] Inflate(byte[] input)
        {
            inflater.Reset();
            inflater.SetInput(input, 0, input.Length - 2);

            using (MemoryStream ms = new MemoryStream())
            {
                byte[] outputBuffer = new byte[1024];
                int    read;

                while ((read = inflater.Inflate(outputBuffer)) > 0)
                {
                    ms.Write(outputBuffer, 0, read);

                    if (inflater.IsFinished)
                    {
                        break;
                    }
                }

                return(ms.ToArray());
            }
        }
示例#26
0
        private void ExpandBlock(Stream uncompressedDataBlockStream, Stream compressedDataBlockStream, CFFOLDER.CFTYPECOMPRESS compressionType, LzxDecoder lzx, Inflater inf)
        {
            switch (compressionType)
            {
            case CFFOLDER.CFTYPECOMPRESS.TYPE_LZX:
            {
                lzx.Decompress(compressedDataBlockStream, (int)compressedDataBlockStream.Length, uncompressedDataBlockStream, (int)uncompressedDataBlockStream.Length);
                break;
            }

            case CFFOLDER.CFTYPECOMPRESS.TYPE_NONE:
            {
                compressedDataBlockStream.CopyTo(uncompressedDataBlockStream);
                break;
            }

            case CFFOLDER.CFTYPECOMPRESS.TYPE_MSZIP:
            {
                using (var br = new BinaryReader(compressedDataBlockStream))
                    using (var bw = new BinaryWriter(uncompressedDataBlockStream))
                    {
                        byte[] inBuffer = br.ReadBytes((int)br.BaseStream.Length);
                        inf.SetInput(inBuffer);
                        byte[] outBuffer = new byte[bw.BaseStream.Length];
                        int    ret       = inf.Inflate(outBuffer);
                        if (ret == 0)
                        {
                            throw new Exception("Inflate failed");
                        }
                        bw.Write(outBuffer);
                        inf.Reset();
                    }
                break;
            }
            }
        }
示例#27
0
        public static byte[] Inflate(byte[] inputData)
        {
            var inflater = new Inflater();

            inflater.SetInput(inputData);

            using (var ms = new MemoryStream())
            {
                var outputBuffer = new byte[65536 * 4];
                while (inflater.IsNeedingInput == false)
                {
                    var read = inflater.Inflate(outputBuffer);
                    ms.Write(outputBuffer, 0, read);

                    if (inflater.IsFinished == true)
                    {
                        break;
                    }
                }
                inflater.Reset();

                return(ms.ToArray());
            }
        }
示例#28
0
        /// <summary>
        /// Reads a MPK from a binary reader
        /// </summary>
        /// <param name="rdr">The binary reader pointing to the MPK</param>
        private void ReadArchive(BinaryReader rdr)
        {
            _files.Clear();

            _crc.Value = 0;
            _sizeDir   = 0;
            _sizeName  = 0;
            _numFiles  = 0;

            var buf = new byte[16];

            rdr.Read(buf, 0, 16);

            for (byte i = 0; i < 16; ++i)
            {
                buf[i] ^= i;
            }

            _crc.Value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
            _sizeDir   = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
            _sizeName  = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
            _numFiles  = (buf[12] << 24) | (buf[13] << 16) | (buf[14] << 8) | buf[15];

            buf = new byte[_sizeName];
            rdr.Read(buf, 0, _sizeName);

            var inf = new Inflater();

            inf.SetInput(buf);
            buf = new byte[1024];
            inf.Inflate(buf);
            buf[inf.TotalOut] = 0;

            _name = Marshal.ConvertToString(buf);

            long totalin = 0;

            buf = ReadDirectory(rdr, ref totalin);

            using (var directory = new MemoryStream(buf))
            {
                long pos = rdr.BaseStream.Position;
                long len = rdr.BaseStream.Seek(0, SeekOrigin.End);
                rdr.BaseStream.Position = pos;

                buf = new byte[len - pos];
                rdr.Read(buf, 0, buf.Length);

                using (var files = new MemoryStream(buf))
                {
                    rdr.BaseStream.Position = pos - totalin;
                    buf = new byte[totalin];
                    rdr.Read(buf, 0, buf.Length);

                    var crc = new Crc32();
                    crc.Reset();
                    crc.Update(buf);

                    if (crc.Value != _crc.Value)
                    {
                        throw new Exception("Invalid or corrupt MPK");
                    }

                    while (directory.Position < directory.Length && files.Position < files.Length)
                    {
                        crc.Reset();

                        buf = new byte[MPKFileHeader.MaxSize];
                        directory.Read(buf, 0, MPKFileHeader.MaxSize);

                        MPKFileHeader hdr;

                        using (var hdrStream = new MemoryStream(buf))
                        {
                            using (var hdrRdr = new BinaryReader(hdrStream, Encoding.UTF8))
                            {
                                hdr = new MPKFileHeader(hdrRdr);
                            }
                        }

                        var compbuf = new byte[hdr.CompressedSize];
                        files.Read(compbuf, 0, compbuf.Length);

                        crc.Update(compbuf, 0, compbuf.Length);

                        inf.Reset();
                        inf.SetInput(compbuf, 0, compbuf.Length);
                        buf = new byte[hdr.UncompressedSize];
                        inf.Inflate(buf, 0, buf.Length);

                        var file = new MPKFile(compbuf, buf, hdr);

                        if (crc.Value != hdr.CRC.Value)
                        {
                            OnInvalidFile(file);
                            continue;
                        }

                        _files.Add(hdr.Name.ToLower(), file);
                    }
                }
            }
        }
示例#29
0
        public static int DecompressBlock(byte[] inBuffer, int inLength, byte[] outBuffer, bool multi)
        {
            byte[] tempBuffer;

            if (!multi)
            {
                return(DclCompression.DecompressBlock(inBuffer, 0, inLength, outBuffer));
            }
            else             // Examinate first byte for finding compression methods used
            {
                switch (inBuffer[0])
                {
                case 0x01:                         // Huffman
                    throw new MpqCompressionNotSupportedException(0x01, "Huffman");

                case 0x02:            // Zlib (Deflate/Inflate)
#if USE_SHARPZIPLIB                   // Use SharpZipLib's Deflate implementation
                    Inflater.Reset(); // The first property read will initialize the field…
                    inflater.SetInput(inBuffer, 1, inLength - 1);
                    return(inflater.Inflate(outBuffer));
#else // Use .NET 2.0's built-in inflate algorithm
                    using (var inStream = new MemoryStream(inBuffer, 3, inLength - 7, false, false))
                        using (var outStream = new DeflateStream(inStream, CompressionMode.Decompress))
                            outStream.Read(outBuffer, 0, outBuffer.Length);
#endif
                case 0x08:                         // PKWare DCL (Implode/Explode)
                    return(DclCompression.DecompressBlock(inBuffer, 1, inLength - 1, outBuffer));

                case 0x10: // BZip2
#if USE_SHARPZIPLIB        // Use SharpZipLib for decompression
                    using (var inStream = new MemoryStream(inBuffer, 1, inLength - 1, false, false))
                        using (var outStream = new BZip2InputStream(inStream))
                            return(outStream.Read(outBuffer, 0, outBuffer.Length));
#else
                    throw new CompressionNotSupportedException("BZip2");
#endif
                case 0x12:                         // LZMA
                    using (var inStream = new MemoryStream(inBuffer, 1, inLength - 1, false, false))
                        using (var outStream = new MemoryStream(outBuffer, true))
                        {
                            lzmaDecoder.Code(inStream, outStream, inStream.Length, outStream.Length, null);
                            return(checked ((int)outStream.Position));
                        }

                case 0x20:                         // Sparse
                    return(SparseCompression.DecompressBlock(inBuffer, 1, inLength - 1, outBuffer));

                case 0x22:            // Sparse + Deflate
#if USE_SHARPZIPLIB                   // Use SharpZipLib's Deflate implementation
                    Inflater.Reset(); // The first property read will initialize the field…
                    inflater.SetInput(inBuffer, 1, inLength - 1);
                    tempBuffer = CommonMethods.GetSharedBuffer(outBuffer.Length);
                    return(SparseCompression.DecompressBlock(tempBuffer, 0, inflater.Inflate(tempBuffer), outBuffer));
#else // Use .NET 2.0's built-in inflate algorithm
                    using (var inStream = new MemoryStream(inBuffer, 3, inLength - 7, false, false))
                        using (var inoutStream = new DeflateStream(inStream, CompressionMode.Decompress))
                            using (var outStream = new SparseInputStream(inoutStream))
                                return(outStream.Read(outBuffer, 0, outBuffer.Length));
#endif
                case 0x30: // Sparse + BZip2
#if USE_SHARPZIPLIB        // Use SharpZipLib for decompression
                    using (var inStream = new MemoryStream(inBuffer, 1, inLength - 1, false, false))
                        using (var inoutStream = new BZip2InputStream(inStream))
                            using (var outStream = new SparseInputStream(inoutStream))
                                return(outStream.Read(outBuffer, 0, outBuffer.Length));
#else
                    throw new CompressionNotSupportedException("Sparse + BZip2");
#endif
                case 0x40:                         // Mono IMA ADPCM
                    throw new MpqCompressionNotSupportedException(0x40, "Mono IMA ADPCM");

                case 0x41:                         // Mono IMA ADPCM + Huffman
                    throw new MpqCompressionNotSupportedException(0x41, "Mono IMA ADPCM + Huffman");

                case 0x48:                         // Mono IMA ADPCM + Implode
                    throw new MpqCompressionNotSupportedException(0x48, "Mono IMA ADPCM + Implode");

                case 0x80:                         // Stereo IMA ADPCM
                    throw new MpqCompressionNotSupportedException(0x80, "Stereo IMA ADPCM");

                case 0x81:                         // Stereo IMA ADPCM + Huffman
                    throw new MpqCompressionNotSupportedException(0x81, "Stereo IMA ADPCM + Huffman");

                case 0x88:                         // Stereo IMA ADPCM + Implode
                    throw new MpqCompressionNotSupportedException(0x88, "Stereo IMA ADPCM + Implode");

                default:
                    throw new MpqCompressionNotSupportedException(inBuffer[0]);
                }
            }
        }
示例#30
0
    static int Inflate(Inflater inf, byte [] src, byte [] dest)
    {
        int offset, length, remain;

        inf.Reset ();
        inf.SetInput (src);

        offset = 0;
        while (!inf.IsNeedingInput) {
            remain = Math.Min (dest.Length - offset, BlockSize);
            if (remain == 0)
                break;

            length = inf.Inflate (dest, offset, remain);
            offset += length;
        }

        return inf.TotalOut;
    }
示例#31
0
        public static void Trim(IntPtr hwnd, string In, string Out, ReportProgressDelegate del)
        {
            NativeMethods.ddsInit(hwnd);
            var  br = new BinaryReader(File.OpenRead(In), Encoding.Default);
            var  bw = new BinaryWriter(File.Create(Out), Encoding.Default);
            var  sb = new StringBuilder(64);
            var  inf = new Inflater();
            bool Compressed, SkipName;

            if (br.ReadInt32() != 0x00415342)
            {
                throw new Exception("Invalid bsa");
            }
            var version = br.ReadUInt32();

            bw.Write(0x00415342);
            bw.Write(version);
            bw.Write(br.ReadInt32());
            var flags = br.ReadUInt32();

            if ((flags & 0x004) > 0)
            {
                Compressed = true;
                flags     ^= 0x4;
            }
            else
            {
                Compressed = false;
            }
            if ((flags & 0x100) > 0 && version == 0x68)
            {
                SkipName = true;
            }
            else
            {
                SkipName = false;
            }
            flags ^= 0x2;
            var FolderCount = br.ReadInt32();
            var FileCount   = br.ReadInt32();

            bw.Write(flags);

            bw.Write(FolderCount);
            bw.Write(FileCount);
            bw.Write(br.ReadInt32());
            bw.Write(br.ReadInt32());
            bw.Write(br.ReadInt32());

            var folderFileCount = new int[FolderCount];

            for (var i = 0; i < FolderCount; i++)
            {
                bw.Write(br.ReadInt64());
                folderFileCount[i] = br.ReadInt32();
                bw.Write(folderFileCount[i]);
                bw.Write(br.ReadInt32());
            }
            var fileLengths   = new int[FileCount];
            var offsetOffsets = new long[FileCount];
            var fileOffsets   = new uint[FileCount];
            var parsefiles    = new bool[FileCount];
            var file          = 0;

            for (var i = 0; i < FolderCount; i++)
            {
                var len = br.ReadByte();
                bw.Write(len);
                sb.Length = 0;
                while (--len > 0)
                {
                    var c = br.ReadChar();
                    sb.Append(c);
                    bw.Write(c);
                }
                br.ReadByte();
                bw.Write((byte)0);
                var parse = true;
                if (sb.ToString().StartsWith("textures\\interface\\"))
                {
                    parse = false;
                }

                for (var j = 0; j < folderFileCount[i]; j++)
                {
                    bw.Write(br.ReadUInt64());
                    offsetOffsets[file] = br.BaseStream.Position;
                    fileLengths[file]   = br.ReadInt32();
                    bw.Write(fileLengths[file]);
                    fileOffsets[file] = br.ReadUInt32();
                    bw.Write(fileOffsets[file]);
                    parsefiles[file] = parse;
                    file++;
                }
            }

            for (var i = 0; i < FileCount; i++)
            {
                sb.Length = 0;
                while (true)
                {
                    var c = (char)br.ReadByte();
                    //bw.Write(c);
                    if (c == '\0')
                    {
                        break;
                    }
                    sb.Append(c);
                }
                if (!sb.ToString().EndsWith(".dds", StringComparison.OrdinalIgnoreCase))
                {
                    parsefiles[i] = false;
                }
            }

            for (var i = 0; i < FileCount; i++)
            {
                if ((i % 100) == 0)
                {
                    del("Processing file " + i + " of " + FileCount);
                }
                br.BaseStream.Position = fileOffsets[i];
                var offset = bw.BaseStream.Position;
                var add    = 0;
                if (SkipName)
                {
                    var len = br.ReadByte();
                    bw.Write(len);
                    bw.Write(br.ReadBytes(len + 1));
                    add = len + 2;
                }
                var compressed2 = Compressed;
                if ((fileLengths[i] & (1 << 30)) != 0)
                {
                    compressed2     = !compressed2;
                    fileLengths[i] ^= (1 << 30);
                }
                if (!compressed2)
                {
                    var bytes = new byte[fileLengths[i]];
                    br.Read(bytes, 0, fileLengths[i]);
                    Commit(bw, offsetOffsets[i], bytes, offset, add, parsefiles[i]);
                }
                else
                {
                    var uncompressed = new byte[br.ReadUInt32()];
                    var compressed   = new byte[fileLengths[i] - 4];
                    br.Read(compressed, 0, fileLengths[i] - 4);
                    inf.Reset();
                    inf.SetInput(compressed);
                    inf.Inflate(uncompressed);
                    Commit(bw, offsetOffsets[i], uncompressed, offset, add, parsefiles[i]);
                }
            }

            br.Close();
            bw.Close();
            NativeMethods.ddsClose();
        }