public static byte[] Compress(byte[] inputBytes) { int num = inputBytes.Length * 2; byte[] src = new byte[num]; int num2; for (num2 = CLZF2.lzf_compress(inputBytes, ref src); num2 == 0; num2 = CLZF2.lzf_compress(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 DoCompression() { if (Features.UseDifferentialSerialization) { var provider = Chunk.world.blockProvider; int blockPosSize = StructSerialization.TSSize <BlockPos> .ValueSize; int blockDataSize = StructSerialization.TSSize <BlockData> .ValueSize; int posLenBytes = m_blocksModified.Length * blockPosSize; int blkLenBytes = m_blocksModified.Length * blockDataSize; m_positionsBytes = new byte[posLenBytes]; m_blocksBytes = new byte[blkLenBytes]; unsafe { // Pack positions to a byte array fixed(byte *pDst = m_positionsBytes) { for (int i = 0, j = 0; i < m_blocksModified.Length; i++, j += blockPosSize) { *(BlockPos *)&pDst[j] = m_positionsModified[i]; } } // Pack block data to a byte array fixed(BlockData *pBD = m_blocksModified) fixed(byte *pDst = m_blocksBytes) { for (int i = 0, j = 0; i < m_blocksModified.Length; i++, j += blockDataSize) { BlockData *bd = &pBD[i]; // Convert block types from internal optimized version into global types ushort typeInConfig = provider.GetConfig(bd->Type).typeInConfig; *(BlockData *)&pDst[j] = new BlockData(typeInConfig, bd->Solid); } } } } else { var pools = Globals.WorkPool.GetPool(Chunk.ThreadID); var provider = Chunk.world.blockProvider; int blockDataSize = StructSerialization.TSSize <BlockData> .ValueSize; int requestedByteSize = Env.ChunkSizePow3 * blockDataSize; // Pop large enough buffers from the pool byte[] tmp = pools.ByteArrayPool.Pop(requestedByteSize); byte[] bytesCompressed = pools.ByteArrayPool.Pop(requestedByteSize); { ChunkBlocks blocks = Chunk.Blocks; int i = 0; 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 = blocks.Get(index); // Convert block types from internal optimized version into global types ushort typeInConfig = provider.GetConfig(bd.Type).typeInConfig; // Write updated block data to destination buffer unsafe { fixed(byte *pDst = tmp) { *(BlockData *)&pDst[i] = new BlockData(typeInConfig, bd.Solid); } } } } } // Compress bytes int blkLenBytes = CLZF2.lzf_compress(tmp, requestedByteSize, ref bytesCompressed); m_blocksBytes = new byte[blkLenBytes]; // Copy data from a temporary buffer to block buffer Array.Copy(bytesCompressed, 0, m_blocksBytes, 0, blkLenBytes); } // Return our temporary buffer back to the pool pools.ByteArrayPool.Push(bytesCompressed); pools.ByteArrayPool.Push(tmp); } return(true); }