static public Stream compressData(byte[] inputData)
        {
            MemoryStream ouputStream         = new MemoryStream();
            uint         compressedSize      = 0;
            uint         dataBlockLeft       = (uint)inputData.Length;
            uint         newNumBlocks        = ((uint)inputData.Length + maxBlockSize - 1) / maxBlockSize;
            List <Package.ChunkBlock> blocks = new List <Package.ChunkBlock>();

            using (MemoryStream inputStream = new MemoryStream(inputData))
            {
                // skip blocks header and table - filled later
                ouputStream.Seek(SizeOfChunk + SizeOfChunkBlock * newNumBlocks, SeekOrigin.Begin);

                for (int b = 0; b < newNumBlocks; b++)
                {
                    Package.ChunkBlock block = new Package.ChunkBlock();
                    block.uncomprSize        = Math.Min(maxBlockSize, dataBlockLeft);
                    dataBlockLeft           -= block.uncomprSize;
                    block.uncompressedBuffer = inputStream.ReadToBuffer(block.uncomprSize);
                    blocks.Add(block);
                }
            }

            Parallel.For(0, blocks.Count, b =>
            {
                Package.ChunkBlock block = blocks[b];
                block.compressedBuffer   = new ZlibHelper.Zlib().Compress(block.uncompressedBuffer);
                if (block.compressedBuffer.Length == 0)
                {
                    throw new Exception("Compression failed!");
                }
                block.comprSize = (uint)block.compressedBuffer.Length;
                blocks[b]       = block;
            });

            for (int b = 0; b < blocks.Count; b++)
            {
                Package.ChunkBlock block = blocks[b];
                ouputStream.Write(block.compressedBuffer, 0, (int)block.comprSize);
                compressedSize += block.comprSize;
            }

            ouputStream.SeekBegin();
            ouputStream.WriteUInt32(compressedSize);
            ouputStream.WriteInt32(inputData.Length);
            foreach (Package.ChunkBlock block in blocks)
            {
                ouputStream.WriteUInt32(block.comprSize);
                ouputStream.WriteUInt32(block.uncomprSize);
            }

            return(ouputStream);
        }
        static public byte[] decompressData(Stream stream, long compressedSize)
        {
            uint compressedChunkSize   = stream.ReadUInt32();
            uint uncompressedChunkSize = stream.ReadUInt32();

            byte[] data        = new byte[uncompressedChunkSize];
            uint   blocksCount = (uncompressedChunkSize + maxBlockSize - 1) / maxBlockSize;

            if ((compressedChunkSize + SizeOfChunk + SizeOfChunkBlock * blocksCount) != compressedSize)
            {
                throw new Exception("not match");
            }

            List <Package.ChunkBlock> blocks = new List <Package.ChunkBlock>();

            for (uint b = 0; b < blocksCount; b++)
            {
                Package.ChunkBlock block = new Package.ChunkBlock();
                block.comprSize   = stream.ReadUInt32();
                block.uncomprSize = stream.ReadUInt32();
                blocks.Add(block);
            }

            for (int b = 0; b < blocks.Count; b++)
            {
                Package.ChunkBlock block = blocks[b];
                block.compressedBuffer   = stream.ReadToBuffer(blocks[b].comprSize);
                block.uncompressedBuffer = new byte[maxBlockSize * 2];
                blocks[b] = block;
            }

            Parallel.For(0, blocks.Count, b =>
            {
                uint dstLen = 0;
                Package.ChunkBlock block = blocks[b];
                dstLen = new ZlibHelper.Zlib().Decompress(block.compressedBuffer, block.comprSize, block.uncompressedBuffer);
                if (dstLen != block.uncomprSize)
                {
                    throw new Exception("Decompressed data size not expected!");
                }
            });

            int dstPos = 0;

            for (int b = 0; b < blocks.Count; b++)
            {
                Buffer.BlockCopy(blocks[b].uncompressedBuffer, 0, data, dstPos, (int)blocks[b].uncomprSize);
                dstPos += (int)blocks[b].uncomprSize;
            }

            return(data);
        }
Example #3
0
        private byte[] decompressTexture(MemoryStream stream, StorageTypes type, int uncompressedSize, int compressedSize)
        {
            byte[] data     = new byte[uncompressedSize];
            uint   blockTag = stream.ReadUInt32();

            if (blockTag != textureTag)
            {
                throw new Exception("not match");
            }
            uint blockSize = stream.ReadUInt32();

            if (blockSize != maxBlockSize)
            {
                throw new Exception("not match");
            }
            uint compressedChunkSize   = stream.ReadUInt32();
            uint uncompressedChunkSize = stream.ReadUInt32();

            if (uncompressedChunkSize != uncompressedSize)
            {
                throw new Exception("not match");
            }

            uint blocksCount = (uncompressedChunkSize + maxBlockSize - 1) / maxBlockSize;

            if ((compressedChunkSize + SizeOfChunk + SizeOfChunkBlock * blocksCount) != compressedSize)
            {
                throw new Exception("not match");
            }

            List <Package.ChunkBlock> blocks = new List <Package.ChunkBlock>();

            for (uint b = 0; b < blocksCount; b++)
            {
                Package.ChunkBlock block = new Package.ChunkBlock();
                block.comprSize   = stream.ReadUInt32();
                block.uncomprSize = stream.ReadUInt32();
                blocks.Add(block);
            }

            for (int b = 0; b < blocks.Count; b++)
            {
                Package.ChunkBlock block = blocks[b];
                block.compressedBuffer   = stream.ReadToBuffer(blocks[b].comprSize);
                block.uncompressedBuffer = new byte[maxBlockSize * 2];
                blocks[b] = block;
            }

            if (type == StorageTypes.extLZO || type == StorageTypes.pccLZO)
            {
                for (int b = 0; b < blocks.Count; b++)
                {
                    uint dstLen = 0;
                    Package.ChunkBlock block = blocks[b];
                    dstLen = LZO2Helper.LZO2.Decompress(block.compressedBuffer, block.comprSize, block.uncompressedBuffer);
                    if (dstLen != block.uncomprSize)
                    {
                        throw new Exception("Decompressed data size not expected!");
                    }
                }
            }
            else
            {
                Parallel.For(0, blocks.Count, b =>
                {
                    uint dstLen = 0;
                    Package.ChunkBlock block = blocks[b];
                    if (type == StorageTypes.extZlib || type == StorageTypes.pccZlib)
                    {
                        dstLen = ZlibHelper.Zlib.Decompress(block.compressedBuffer, block.comprSize, block.uncompressedBuffer);
                    }
                    if (dstLen != block.uncomprSize)
                    {
                        throw new Exception("Decompressed data size not expected!");
                    }
                });
            }

            int dstPos = 0;

            for (int b = 0; b < blocks.Count; b++)
            {
                Buffer.BlockCopy(blocks[b].uncompressedBuffer, 0, data, dstPos, (int)blocks[b].uncomprSize);
                dstPos += (int)blocks[b].uncomprSize;
            }

            return(data);
        }
Example #4
0
        public byte[] compressTexture(byte[] inputData, StorageTypes type)
        {
            using (MemoryStream ouputStream = new MemoryStream())
            {
                uint compressedSize = 0;
                uint dataBlockLeft  = (uint)inputData.Length;
                uint newNumBlocks   = ((uint)inputData.Length + maxBlockSize - 1) / maxBlockSize;
                List <Package.ChunkBlock> blocks = new List <Package.ChunkBlock>();
                using (MemoryStream inputStream = new MemoryStream(inputData))
                {
                    // skip blocks header and table - filled later
                    ouputStream.Seek(SizeOfChunk + SizeOfChunkBlock * newNumBlocks, SeekOrigin.Begin);

                    for (int b = 0; b < newNumBlocks; b++)
                    {
                        Package.ChunkBlock block = new Package.ChunkBlock();
                        block.uncomprSize        = Math.Min(maxBlockSize, dataBlockLeft);
                        dataBlockLeft           -= block.uncomprSize;
                        block.uncompressedBuffer = inputStream.ReadToBuffer(block.uncomprSize);
                        blocks.Add(block);
                    }
                }

                if (type == StorageTypes.extLZO || type == StorageTypes.pccLZO)
                {
                    for (int b = 0; b < blocks.Count; b++)
                    {
                        Package.ChunkBlock block = blocks[b];
                        block.compressedBuffer = LZO2Helper.LZO2.Compress(block.uncompressedBuffer);
                        if (block.compressedBuffer.Length == 0)
                        {
                            throw new Exception("Compression failed!");
                        }
                        block.comprSize = (uint)block.compressedBuffer.Length;
                        blocks[b]       = block;
                    }
                }
                else
                {
                    Parallel.For(0, blocks.Count, b =>
                    {
                        Package.ChunkBlock block = blocks[b];
                        if (type == StorageTypes.extZlib || type == StorageTypes.pccZlib)
                        {
                            block.compressedBuffer = ZlibHelper.Zlib.Compress(block.uncompressedBuffer);
                        }
                        else
                        {
                            throw new Exception("Compression type not expected!");
                        }
                        if (block.compressedBuffer.Length == 0)
                        {
                            throw new Exception("Compression failed!");
                        }
                        block.comprSize = (uint)block.compressedBuffer.Length;
                        blocks[b]       = block;
                    });
                }

                for (int b = 0; b < blocks.Count; b++)
                {
                    Package.ChunkBlock block = blocks[b];
                    ouputStream.Write(block.compressedBuffer, 0, (int)block.comprSize);
                    compressedSize += block.comprSize;
                }

                ouputStream.SeekBegin();
                ouputStream.WriteUInt32(textureTag);
                ouputStream.WriteUInt32(maxBlockSize);
                ouputStream.WriteUInt32(compressedSize);
                ouputStream.WriteInt32(inputData.Length);
                foreach (Package.ChunkBlock block in blocks)
                {
                    ouputStream.WriteUInt32(block.comprSize);
                    ouputStream.WriteUInt32(block.uncomprSize);
                }

                return(ouputStream.ToArray());
            }
        }