private static void UE4ChunkUnzip(string source, string destination) { if (!File.Exists(source)) { return; } using (BinaryReader inReader = new BinaryReader(File.Open(source, FileMode.Open))) { using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(destination, FileMode.Create))) { FCompressedChunkInfo fcompressedChunkInfo1 = new FCompressedChunkInfo(); fcompressedChunkInfo1.Serialize(inReader); FCompressedChunkInfo fcompressedChunkInfo2 = new FCompressedChunkInfo(); fcompressedChunkInfo2.Serialize(inReader); long num1 = fcompressedChunkInfo1.CompressedSize; long num2 = fcompressedChunkInfo1.UncompressedSize; if (num2 == 2653586369L) { num2 = 131072L; } long length = (fcompressedChunkInfo2.UncompressedSize + num2 - 1L) / num2; FCompressedChunkInfo[] fcompressedChunkInfoArray = new FCompressedChunkInfo[length]; long val2 = 0L; for (int index = 0; index < length; ++index) { fcompressedChunkInfoArray[index] = new FCompressedChunkInfo(); fcompressedChunkInfoArray[index].Serialize(inReader); val2 = Math.Max(fcompressedChunkInfoArray[index].CompressedSize, val2); } for (long index = 0L; index < length; ++index) { FCompressedChunkInfo fcompressedChunkInfo3 = fcompressedChunkInfoArray[index]; byte[] buffer = ZlibStream.UncompressBuffer(inReader.ReadBytes((int)fcompressedChunkInfo3.CompressedSize)); binaryWriter.Write(buffer); } } } }
protected byte[] LoadCompressedChunk(BinaryReader reader) { try { FCompressedChunkInfo PackageFileTag = new FCompressedChunkInfo(); PackageFileTag.CompressedSize = reader.ReadInt64(); PackageFileTag.UncompressedSize = reader.ReadInt64(); FCompressedChunkInfo Summary = new FCompressedChunkInfo(); Summary.CompressedSize = reader.ReadInt64(); Summary.UncompressedSize = reader.ReadInt64(); bool bWasByteSwapped = PackageFileTag.CompressedSize != PACKAGE_FILE_TAG; bool bHeaderWasValid = true; if (bWasByteSwapped) { bHeaderWasValid = PackageFileTag.CompressedSize == PACKAGE_FILE_TAG_SWAPPED; if (bHeaderWasValid) { // not supported //Summary.CompressedSize = BYTESWAP_ORDER64(Summary.CompressedSize); //Summary.UncompressedSize = BYTESWAP_ORDER64(Summary.UncompressedSize); //PackageFileTag.UncompressedSize = BYTESWAP_ORDER64(PackageFileTag.UncompressedSize); } } else { bHeaderWasValid = PackageFileTag.CompressedSize == PACKAGE_FILE_TAG; } // Handle change in compression chunk size in backward compatible way. long LoadingCompressionChunkSize = PackageFileTag.UncompressedSize; if (LoadingCompressionChunkSize == PACKAGE_FILE_TAG) { LoadingCompressionChunkSize = LOADING_COMPRESSION_CHUNK_SIZE; } // Figure out how many chunks there are going to be based on uncompressed size and compression chunk size. long TotalChunkCount = (Summary.UncompressedSize + LoadingCompressionChunkSize - 1) / LoadingCompressionChunkSize; // Allocate compression chunk infos and serialize them, keeping track of max size of compression chunks used. FCompressedChunkInfo[] CompressionChunks = new FCompressedChunkInfo[TotalChunkCount]; long MaxCompressedSize = 0; for (int ChunkIndex = 0; ChunkIndex < TotalChunkCount; ChunkIndex++) { CompressionChunks[ChunkIndex].CompressedSize = reader.ReadInt64(); CompressionChunks[ChunkIndex].UncompressedSize = reader.ReadInt64(); if (bWasByteSwapped) { // not supported //CompressionChunks[ChunkIndex].CompressedSize = BYTESWAP_ORDER64(CompressionChunks[ChunkIndex].CompressedSize); //CompressionChunks[ChunkIndex].UncompressedSize = BYTESWAP_ORDER64(CompressionChunks[ChunkIndex].UncompressedSize); } MaxCompressedSize = Math.Max(CompressionChunks[ChunkIndex].CompressedSize, MaxCompressedSize); } byte[] DeCompressedBuffer = new byte[Summary.UncompressedSize]; int offset = 0; // Iterate over all chunks, serialize them into memory and decompress them directly into the destination pointer for (long ChunkIndex = 0; ChunkIndex < TotalChunkCount; ChunkIndex++) { // Read compressed data. byte[] initialSkip = reader.ReadBytes(2); byte[] CompressedBuffer = reader.ReadBytes((int)CompressionChunks[ChunkIndex].CompressedSize - 6); byte[] finalSkip = reader.ReadBytes(4); MemoryStream ms = new MemoryStream(CompressedBuffer); DeflateStream gzip = new DeflateStream(ms, CompressionMode.Decompress); gzip.Read(DeCompressedBuffer, offset, (int)CompressionChunks[ChunkIndex].UncompressedSize); // Decompress into dest pointer directly. offset += (int)CompressionChunks[ChunkIndex].UncompressedSize; } return(DeCompressedBuffer); } catch { return(null); } }