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); }
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); } }
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); } }
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); }
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); } }
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); }
/// <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(); }
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(); }
/** * 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); } }
/// <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(); } } }
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); }
/// <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; } }
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; }
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(); } }
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; }
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; }
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(); } }
/// <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; } }
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)); }
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); }
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); } }
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()); } }
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; } } }
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()); } }
/// <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); } } } }
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]); } } }
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; }
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(); }