private ShaderSubProgramBlob ReadSubProgramBlobs(AssetLayout layout, MemoryStream memStream, uint offset, uint compressedLength, uint decompressedLength) { memStream.Position = offset; byte[] decompressedBuffer = new byte[decompressedLength]; using (Lz4DecodeStream lz4Stream = new Lz4DecodeStream(memStream, (int)compressedLength)) { lz4Stream.ReadBuffer(decompressedBuffer, 0, decompressedBuffer.Length); } using (MemoryStream blobMem = new MemoryStream(decompressedBuffer)) { using (AssetReader blobReader = new AssetReader(blobMem, EndianType.LittleEndian, layout)) { ShaderSubProgramBlob blob = new ShaderSubProgramBlob(); blob.Read(blobReader); return(blob); } } }
private void ReadBlob(AssetLayout layout, MemoryStream memStream, uint compressedLength, uint decompressedLength, int segment) { byte[] decompressedBuffer = new byte[decompressedLength]; using (Lz4DecodeStream lz4Stream = new Lz4DecodeStream(memStream, compressedLength)) { lz4Stream.ReadBuffer(decompressedBuffer, 0, decompressedBuffer.Length); } using (MemoryStream blobMem = new MemoryStream(decompressedBuffer)) { using (AssetReader blobReader = new AssetReader(blobMem, EndianType.LittleEndian, layout)) { if (segment == 0) { Entries = blobReader.ReadAssetArray <ShaderSubProgramEntry>(); SubPrograms = new ShaderSubProgram[Entries.Length]; } ReadSegment(blobReader, segment); } } }
public SmartStream ReadEntry(BundleFileEntry entry) { if (m_isDisposed) { throw new ObjectDisposedException(nameof(BundleFileBlockReader)); } // find out block offsets int blockIndex; long blockCompressedOffset = 0; long blockDecompressedOffset = 0; for (blockIndex = 0; blockDecompressedOffset + m_metadata.BlockInfos[blockIndex].DecompressedSize <= entry.Offset; blockIndex++) { blockCompressedOffset += m_metadata.BlockInfos[blockIndex].CompressedSize; blockDecompressedOffset += m_metadata.BlockInfos[blockIndex].DecompressedSize; } long entryOffsetInsideBlock = entry.Offset - blockDecompressedOffset; using (SmartStream entryStream = CreateStream(entry.Size)) { long left = entry.Size; m_stream.Position = m_dataOffset + blockCompressedOffset; // copy data of all blocks used by current entry to new stream while (left > 0) { long blockStreamOffset; Stream blockStream; BlockInfo block = m_metadata.BlockInfos[blockIndex]; if (m_cachedBlockIndex == blockIndex) { // data of the previous entry is in the same block as this one // so we don't need to unpack it once again. Instead we can use cached stream blockStreamOffset = 0; blockStream = m_cachedBlockStream; m_stream.Position += block.CompressedSize; } else { BundleCompressType compressType = block.Flags.GetCompression(); if (compressType == BundleCompressType.None) { blockStreamOffset = m_dataOffset + blockCompressedOffset; blockStream = m_stream; } else { blockStreamOffset = 0; m_cachedBlockIndex = blockIndex; m_cachedBlockStream.Move(CreateStream(block.DecompressedSize)); switch (compressType) { case BundleCompressType.LZMA: SevenZipHelper.DecompressLZMAStream(m_stream, block.CompressedSize, m_cachedBlockStream, block.DecompressedSize); break; case BundleCompressType.LZ4: case BundleCompressType.LZ4HZ: using (Lz4DecodeStream lzStream = new Lz4DecodeStream(m_stream, block.CompressedSize)) { lzStream.ReadBuffer(m_cachedBlockStream, block.DecompressedSize); } break; default: throw new NotImplementedException($"Bundle compression '{compressType}' isn't supported"); } blockStream = m_cachedBlockStream; } } // consider next offsets: // 1) block - if it is new stream then offset is 0, otherwise offset of this block in the bundle file // 2) entry - if this is first block for current entry then it is offset of this entry related to this block // otherwise 0 long blockSize = block.DecompressedSize - entryOffsetInsideBlock; blockStream.Position = blockStreamOffset + entryOffsetInsideBlock; entryOffsetInsideBlock = 0; long size = Math.Min(blockSize, left); blockStream.CopyStream(entryStream, size); blockIndex++; blockCompressedOffset += block.CompressedSize; left -= size; } if (left < 0) { throw new Exception($"Read more than expected"); } entryStream.Position = 0; return(entryStream.CreateReference()); } }
public override void Read(AssetReader reader) { if (IsSerialized(reader.Version)) { ReadNamedObject(reader); ParsedForm.Read(reader); Platforms = reader.ReadArray((t) => (GPUPlatform)t); uint[] offsets = reader.ReadUInt32Array(); uint[] compressedLengths = reader.ReadUInt32Array(); uint[] decompressedLengths = reader.ReadUInt32Array(); byte[] compressedBlob = reader.ReadByteArray(); reader.AlignStream(); SubProgramBlobs = new ShaderSubProgramBlob[Platforms.Length]; using (MemoryStream memStream = new MemoryStream(compressedBlob)) { for (int i = 0; i < Platforms.Length; i++) { uint offset = offsets[i]; uint compressedLength = compressedLengths[i]; uint decompressedLength = decompressedLengths[i]; memStream.Position = offset; byte[] decompressedBuffer = new byte[decompressedLength]; using (Lz4DecodeStream lz4Stream = new Lz4DecodeStream(memStream, (int)compressedLength)) { lz4Stream.ReadBuffer(decompressedBuffer, 0, decompressedBuffer.Length); } using (MemoryStream blobMem = new MemoryStream(decompressedBuffer)) { using (AssetReader blobReader = new AssetReader(blobMem, EndianType.LittleEndian, reader.Version, reader.Platform, reader.Flags)) { ShaderSubProgramBlob blob = new ShaderSubProgramBlob(); blob.Read(blobReader); SubProgramBlobs[i] = blob; } } } } } else { base.Read(reader); if (IsEncoded(reader.Version)) { uint decompressedSize = reader.ReadUInt32(); int comressedSize = reader.ReadInt32(); if (comressedSize > 0 && decompressedSize > 0) { byte[] subProgramBlob = new byte[comressedSize]; reader.ReadBuffer(subProgramBlob, 0, comressedSize); byte[] decompressedBuffer = new byte[decompressedSize]; using (MemoryStream memStream = new MemoryStream(subProgramBlob)) { using (Lz4DecodeStream lz4Stream = new Lz4DecodeStream(memStream)) { lz4Stream.ReadBuffer(decompressedBuffer, 0, decompressedBuffer.Length); } } using (MemoryStream memStream = new MemoryStream(decompressedBuffer)) { using (AssetReader blobReader = new AssetReader(memStream, EndianType.LittleEndian, reader.Version, reader.Platform, reader.Flags)) { SubProgramBlob.Read(blobReader); } } } reader.AlignStream(); } if (HasFallback(reader.Version)) { Fallback.Read(reader); } if (HasDefaultProperties(reader.Version)) { DefaultProperties.Read(reader); } if (HasStaticProperties(reader.Version)) { StaticProperties.Read(reader); } } if (HasDependencies(reader.Version)) { Dependencies = reader.ReadAssetArray <PPtr <Shader> >(); } if (HasNonModifiableTextures(reader.Version)) { NonModifiableTextures = new Dictionary <string, PPtr <Texture> >(); NonModifiableTextures.Read(reader); } if (HasShaderIsBaked(reader.Version)) { ShaderIsBaked = reader.ReadBoolean(); reader.AlignStream(); } #if UNIVERSAL if (HasErrors(reader.Version, reader.Flags)) { Errors = reader.ReadAssetArray <ShaderError>(); } if (HasDefaultTextures(reader.Version, reader.Flags)) { DefaultTextures = new Dictionary <string, PPtr <Texture> >(); DefaultTextures.Read(reader); } if (HasCompileInfo(reader.Version, reader.Flags)) { CompileInfo.Read(reader); } #endif }
public override void Read(AssetReader reader) { if (IsSerialized(reader.Version)) { ReadBase(reader); ParsedForm.Read(reader); m_platforms = reader.ReadEnum32Array((t) => (GPUPlatform)t); uint[] offsets = reader.ReadUInt32Array(); uint[] compressedLengths = reader.ReadUInt32Array(); uint[] decompressedLengths = reader.ReadUInt32Array(); byte[] compressedBlob = reader.ReadByteArray(); reader.AlignStream(AlignType.Align4); m_subProgramBlobs = new ShaderSubProgramBlob[m_platforms.Length]; using (MemoryStream memStream = new MemoryStream(compressedBlob)) { for (int i = 0; i < m_platforms.Length; i++) { uint offset = offsets[i]; uint compressedLength = compressedLengths[i]; uint decompressedLength = decompressedLengths[i]; memStream.Position = offset; byte[] decompressedBuffer = new byte[decompressedLength]; using (Lz4DecodeStream lz4Stream = new Lz4DecodeStream(memStream, (int)compressedLength)) { lz4Stream.ReadBuffer(decompressedBuffer, 0, decompressedBuffer.Length); } using (MemoryStream blobMem = new MemoryStream(decompressedBuffer)) { using (AssetReader blobReader = new AssetReader(blobMem, reader.Version, reader.Platform, reader.Flags)) { ShaderSubProgramBlob blob = new ShaderSubProgramBlob(); blob.Read(blobReader); m_subProgramBlobs[i] = blob; } } } } } else { base.Read(reader); if (IsEncoded(reader.Version)) { uint decompressedSize = reader.ReadUInt32(); int comressedSize = reader.ReadInt32(); if (comressedSize > 0 && decompressedSize > 0) { byte[] subProgramBlob = new byte[comressedSize]; reader.ReadBuffer(subProgramBlob, 0, comressedSize); byte[] decompressedBuffer = new byte[decompressedSize]; using (MemoryStream memStream = new MemoryStream(subProgramBlob)) { using (Lz4DecodeStream lz4Stream = new Lz4DecodeStream(memStream)) { lz4Stream.ReadBuffer(decompressedBuffer, 0, decompressedBuffer.Length); } } using (MemoryStream memStream = new MemoryStream(decompressedBuffer)) { using (AssetReader blobReader = new AssetReader(memStream, reader.Version, reader.Platform, reader.Flags)) { SubProgramBlob.Read(blobReader); } } } reader.AlignStream(AlignType.Align4); } if (IsReadFallback(reader.Version)) { Fallback.Read(reader); } if (IsReadDefaultProperties(reader.Version)) { DefaultProperties.Read(reader); } if (IsReadStaticProperties(reader.Version)) { StaticProperties.Read(reader); } } if (IsReadDependencies(reader.Version)) { m_dependencies = reader.ReadAssetArray <PPtr <Shader> >(); } if (IsReadNonModifiableTextures(reader.Version)) { m_nonModifiableTextures = new Dictionary <string, PPtr <Texture> >(); m_nonModifiableTextures.Read(reader); } if (IsReadShaderIsBaked(reader.Version)) { ShaderIsBaked = reader.ReadBoolean(); reader.AlignStream(AlignType.Align4); } // editor DefaultTextures // editor CompileInfo }