public async Task Should_fix_tga() { const int chunkIndexThatIsFaulty = 24; var datFile = _compiledControllers.ServiceProvider.GetRequiredService <DatFile>(); // Act await datFile.LoadAsync(_datFileStream); // Assert EmbeddedImageChunk embeddedImageChunk = datFile.Chunks[chunkIndexThatIsFaulty].Should().BeOfType <EmbeddedImageChunk>().Which; using (Stream imageData = await embeddedImageChunk.ReadAsStreamAsync()) { var tgaDetector = new TgaImageFormatDetector(); tgaDetector.GetImageFormat(imageData).Should().Be("tga", "it will return null if not a valid TGA"); } }
/// <summary> /// Writes new image data to the embedded image. /// </summary> /// <param name="imageData">The image data.</param> public async Task WriteAsync(Stream imageData) { if (imageData == null) { throw new ArgumentNullException(nameof(imageData)); } if (!imageData.CanRead) { throw new ArgumentException("The stream does not support reading.", nameof(imageData)); } long currentPos = imageData.Position; int bytesToRead = unchecked ((int)(imageData.Length - currentPos)); if (bytesToRead <= 0) { throw new ArgumentException("No data to read from stream.", nameof(imageData)); } Stream localStream = imageData; try { if (!imageData.CanSeek) { localStream = new MemoryStream(); await imageData.CopyToAsync(localStream).ConfigureAwait(false); localStream.Position = 0; } ImageFormat = _imageFormatDetection.GetFormat(localStream); if (ImageFormat == ImageFormat.Unknown) { // Attempt to apply fixes. TgaImageFormatDetector tgaDetector = _imageFormatDetection.Detectors.OfType <TgaImageFormatDetector>().FirstOrDefault(); if (tgaDetector != null) { using (var ms = new MemoryStream()) { await localStream.CopyToAsync(ms).ConfigureAwait(false); ms.Position = 0; if (tgaDetector.TryApplyFixes(ms)) { ImageFormat = ImageFormat.Tga; } _buffer = ms.ToArray(); return; } } } // Using indirection because we can't write directly to field, so we just use the same ref to the local var. byte[] buffer = _buffer = new byte[bytesToRead]; await localStream.ReadAsync(buffer, 0, bytesToRead).ConfigureAwait(false); } finally { if (localStream != imageData) { localStream.Dispose(); } } }