public static byte[] Decompress(byte[] inputBytes) { int num = inputBytes.Length * 2; byte[] src = new byte[num]; int num2; for (num2 = CLZF2.lzf_decompress(inputBytes, ref src); num2 == 0; num2 = CLZF2.lzf_decompress(inputBytes, ref src)) { num *= 2; src = new byte[num]; } byte[] array = new byte[num2]; Buffer.BlockCopy(src, 0, array, 0, num2); return(array); }
public bool DoDecompression() { var pools = Globals.WorkPool.GetPool(Chunk.ThreadID); var provider = Chunk.world.blockProvider; if (IsDifferential) { int blockPosSize = StructSerialization.TSSize <BlockPos> .ValueSize; int blockDataSize = StructSerialization.TSSize <BlockData> .ValueSize; m_positionsModified = new BlockPos[m_positionsBytes.Length / blockPosSize]; m_blocksModified = new BlockData[m_blocksBytes.Length / blockDataSize]; int i, j; unsafe { // Extract positions fixed(byte *pSrc = m_positionsBytes) { for (i = 0, j = 0; j < m_positionsModified.Length; i += blockPosSize, j++) { m_positionsModified[j] = *(BlockPos *)&pSrc[i]; } } // Extract block data fixed(byte *pSrc = m_blocksBytes) { for (i = 0, j = 0; j < m_blocksModified.Length; i += blockDataSize, j++) { BlockData *bd = (BlockData *)&pSrc[i]; // Convert global block types into internal optimized version ushort type = provider.GetTypeFromTypeInConfig(bd->Type); m_blocksModified[j] = new BlockData(type, bd->Solid); } } } } else { int blockDataSize = StructSerialization.TSSize <BlockData> .ValueSize; int requestedByteSize = Env.ChunkSizePow3 * blockDataSize; // Pop a large enough buffers from the pool var bytes = pools.ByteArrayPool.Pop(requestedByteSize); { // Decompress data int decompressedLength = CLZF2.lzf_decompress(m_blocksBytes, m_blocksBytes.Length, ref bytes); if (decompressedLength != Env.ChunkSizePow3 * blockDataSize) { m_blocksBytes = null; return(false); } // Fill chunk with decompressed data ChunkBlocks blocks = Chunk.Blocks; int i = 0; unsafe { fixed(byte *pSrc = bytes) { int index = Helpers.ZeroChunkIndex; int yOffset = Env.ChunkSizeWithPaddingPow2 - Env.ChunkSize * Env.ChunkSizeWithPadding; int zOffset = Env.ChunkSizeWithPadding - Env.ChunkSize; for (int y = 0; y < Env.ChunkSize; ++y, index += yOffset) { for (int z = 0; z < Env.ChunkSize; ++z, index += zOffset) { for (int x = 0; x < Env.ChunkSize; ++x, i += blockDataSize, ++index) { BlockData *bd = (BlockData *)&pSrc[i]; // Convert global block type into internal optimized version ushort type = provider.GetTypeFromTypeInConfig(bd->Type); blocks.SetRaw(index, new BlockData(type, bd->Solid)); } } } } } } // Return our temporary buffer back to the pool pools.ByteArrayPool.Push(bytes); } ResetTemporary(); return(true); }