private static void DeserializeTexture(ContentManager contentManager, Texture texture, ref ImageDescription imageDescription, ref ContentStorageHeader storageHeader) { using (var content = new ContentStreamingService()) { // Get content storage container var storage = content.GetStorage(ref storageHeader); if (storage is null) { throw new ContentStreamingException("Missing content storage."); } storage.LockChunks(); // Cache data var fileProvider = contentManager.FileProvider; var format = imageDescription.Format; bool isBlockCompressed = (format >= PixelFormat.BC1_Typeless && format <= PixelFormat.BC5_SNorm) || (format >= PixelFormat.BC6H_Typeless && format <= PixelFormat.BC7_UNorm_SRgb); var dataBoxes = new DataBox[imageDescription.MipLevels * imageDescription.ArraySize]; int dataBoxIndex = 0; // Get data boxes data for (int arrayIndex = 0; arrayIndex < imageDescription.ArraySize; arrayIndex++) { for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++) { int mipWidth = imageDescription.Width >> mipIndex; int mipHeight = imageDescription.Height >> mipIndex; if (isBlockCompressed && ((mipWidth % 4) != 0 || (mipHeight % 4) != 0)) { mipWidth = unchecked ((int)(((uint)(mipWidth + 3)) & ~3U)); mipHeight = unchecked ((int)(((uint)(mipHeight + 3)) & ~3U)); } int rowPitch, slicePitch; int widthPacked; int heightPacked; Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked); var chunk = storage.GetChunk(mipIndex); if (chunk == null || chunk.Size != slicePitch * imageDescription.ArraySize) { throw new ContentStreamingException("Data chunk is missing or has invalid size.", storage); } var data = chunk.GetData(fileProvider); if (!chunk.IsLoaded) { throw new ContentStreamingException("Data chunk is not loaded.", storage); } dataBoxes[dataBoxIndex].DataPointer = data + slicePitch * arrayIndex; dataBoxes[dataBoxIndex].RowPitch = rowPitch; dataBoxes[dataBoxIndex].SlicePitch = slicePitch; dataBoxIndex++; } } // Initialize texture texture.InitializeFrom(imageDescription, new TextureViewDescription(), dataBoxes); storage.UnlockChunks(); } }
private static void DeserializeImage(ContentManager contentManager, Image obj, ref ImageDescription imageDescription, ref ContentStorageHeader storageHeader) { using (var content = new ContentStreamingService()) { // Get content storage container var storage = content.GetStorage(ref storageHeader); if (storage == null) { throw new ContentStreamingException("Missing content storage."); } storage.LockChunks(); // Cache data var fileProvider = contentManager.FileProvider; var format = imageDescription.Format; bool isBlockCompressed = (format >= PixelFormat.BC1_Typeless && format <= PixelFormat.BC5_SNorm) || (format >= PixelFormat.BC6H_Typeless && format <= PixelFormat.BC7_UNorm_SRgb); // Calculate total size int size = 0; for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++) { int mipWidth = Math.Max(1, imageDescription.Width >> mipIndex); int mipHeight = Math.Max(1, imageDescription.Height >> mipIndex); if (isBlockCompressed && ((mipWidth % 4) != 0 || (mipHeight % 4) != 0)) { mipWidth = unchecked ((int)(((uint)(mipWidth + 3)) & ~(uint)3)); mipHeight = unchecked ((int)(((uint)(mipHeight + 3)) & ~(uint)3)); } int rowPitch, slicePitch; int widthPacked; int heightPacked; Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked); size += slicePitch; } size *= imageDescription.ArraySize; // Preload chunks for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++) { storage.GetChunk(mipIndex)?.GetData(fileProvider); } // Allocate buffer for image data var buffer = Utilities.AllocateMemory(size); try { // Load image data to the buffer var bufferPtr = buffer; for (int arrayIndex = 0; arrayIndex < imageDescription.ArraySize; arrayIndex++) { for (int mipIndex = 0; mipIndex < imageDescription.MipLevels; mipIndex++) { int mipWidth = Math.Max(1, imageDescription.Width >> mipIndex); int mipHeight = Math.Max(1, imageDescription.Height >> mipIndex); if (isBlockCompressed && ((mipWidth % 4) != 0 || (mipHeight % 4) != 0)) { mipWidth = unchecked ((int)(((uint)(mipWidth + 3)) & ~(uint)3)); mipHeight = unchecked ((int)(((uint)(mipHeight + 3)) & ~(uint)3)); } int rowPitch, slicePitch; int widthPacked; int heightPacked; Image.ComputePitch(format, mipWidth, mipHeight, out rowPitch, out slicePitch, out widthPacked, out heightPacked); var chunk = storage.GetChunk(mipIndex); if (chunk == null || chunk.Size != slicePitch * imageDescription.ArraySize) { throw new ContentStreamingException("Data chunk is missing or has invalid size.", storage); } var data = chunk.GetData(fileProvider); if (!chunk.IsLoaded) { throw new ContentStreamingException("Data chunk is not loaded.", storage); } Utilities.CopyMemory(bufferPtr, data, chunk.Size); bufferPtr += chunk.Size; } } // Initialize image var image = new Image(imageDescription, buffer, 0, null, true); obj.InitializeFrom(image); } catch { // Free memory in case of error Utilities.FreeMemory(buffer); throw; } storage.UnlockChunks(); } }