public Task <Image <TPixel> > DecodeAsync <TPixel>(Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel <TPixel> { if (!stream.CanSeek) { throw new InvalidOperationException("TIFF stream must be seekable."); } return(DecodeCoreAsync <TPixel>(TiffFileContentSource.Create(stream, true), cancellationToken)); }
public Task <IImageInfo> IdentifyAsync(Stream stream, CancellationToken cancellationToken) { if (!stream.CanSeek) { throw new InvalidOperationException("TIFF stream must be seekable."); } return(IdentifyCoreAsync(TiffFileContentSource.Create(stream, true), cancellationToken)); }
public static IEnumerable <object[]> GetContentSources() { // Reference content string file = @"Assets/PhotometricInterpretation/flower-minisblack-big-endian.tif"; byte[] referenceContent = File.ReadAllBytes(file); byte[] clonedContent = new byte[2000 + referenceContent.Length]; referenceContent.CopyTo(clonedContent, 1000); // File source yield return(new object[] { referenceContent, TiffFileContentSource.Create(file, preferAsync: true) }); // Stream source yield return(new object[] { referenceContent, TiffFileContentSource.Create(new MemoryStream(clonedContent, 1000, referenceContent.Length, writable: false), leaveOpen: true) }); // ReadOnlyMemory source yield return(new object[] { referenceContent, TiffFileContentSource.Create(clonedContent.AsMemory(1000, referenceContent.Length)) }); // byte[] source yield return(new object[] { referenceContent, TiffFileContentSource.Create(clonedContent, 1000, referenceContent.Length) }); var mmf = MemoryMappedFile.CreateFromFile(file, FileMode.Open, null, 0, MemoryMappedFileAccess.Read); byte[] mmfContent; using (MemoryMappedViewStream mmfStream = mmf.CreateViewStream(0, 0, MemoryMappedFileAccess.Read)) { mmfContent = new byte[mmfStream.Length]; mmfStream.Read(mmfContent, 0, mmfContent.Length); } // Memory-mapped file source yield return(new object[] { mmfContent, TiffFileContentSource.Create(mmf, leaveOpen: false) }); }
private async Task <IImageInfo> IdentifyCoreAsync(TiffFileContentSource contentSource, CancellationToken cancellationToken) { using TiffFileReader tiff = await TiffFileReader.OpenAsync(contentSource, cancellationToken : cancellationToken).ConfigureAwait(false); TiffImageFileDirectory ifd = await tiff.ReadImageFileDirectoryAsync(cancellationToken).ConfigureAwait(false); TiffImageDecoder decoder = await tiff.CreateImageDecoderAsync(ifd, _options, cancellationToken).ConfigureAwait(false); return(new ImageInfo() { Width = decoder.Width, Height = decoder.Height }); }
private async Task <Image <TPixel> > DecodeCoreAsync <TPixel>(TiffFileContentSource contentSource, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel <TPixel> { using TiffFileReader tiff = await TiffFileReader.OpenAsync(contentSource, cancellationToken : cancellationToken).ConfigureAwait(false); TiffImageFileDirectory ifd = await tiff.ReadImageFileDirectoryAsync(cancellationToken).ConfigureAwait(false); TiffImageDecoder decoder = await tiff.CreateImageDecoderAsync(ifd, _options, cancellationToken).ConfigureAwait(false); Image <TPixel>?image = new Image <TPixel>(_configuration, decoder.Width, decoder.Height); try { await decoder.DecodeAsync(image, cancellationToken).ConfigureAwait(false); return(Interlocked.Exchange <Image <TPixel>?>(ref image, null) !); } finally { image?.Dispose(); } }
public async Task TestRead(byte[] referenceContent, TiffFileContentSource source) { var rand = new Random(42); try { TiffFileContentReader reader = await source.OpenReaderAsync(); // Random read within the range of the file. for (int i = 0; i < 100; i++) { int offset = rand.Next(0, referenceContent.Length); int count = 1; if (offset + 1 < referenceContent.Length) { count = rand.Next(1, referenceContent.Length - offset); } await AssertReadAsync(reader, offset, count, count); } // Read on the edge of the file await AssertReadAsync(reader, referenceContent.Length - 2048, 4096, 2048); // Read past the end of the file. await AssertReadAsync(reader, referenceContent.Length, 4096, 0); await AssertReadAsync(reader, referenceContent.Length + 2048, 4096, 0); } finally { await source.DisposeAsync(); } async Task AssertReadAsync(TiffFileContentReader reader, int fileOffset, int count, int expectedCount) { int readCount; byte[] buffer = ArrayPool <byte> .Shared.Rent(count); try { // Use Memory API Array.Clear(buffer, 0, count); readCount = await reader.ReadAsync(fileOffset, new Memory <byte>(buffer, 0, count), CancellationToken.None); Assert.Equal(expectedCount, readCount); Assert.True(buffer.AsSpan(0, readCount).SequenceEqual(referenceContent.AsSpan(Math.Min(referenceContent.Length, fileOffset), expectedCount))); // Use ArraySegment API Array.Clear(buffer, 0, count); readCount = await reader.ReadAsync(fileOffset, new ArraySegment <byte>(buffer, 0, count), CancellationToken.None); Assert.Equal(expectedCount, readCount); Assert.True(buffer.AsSpan(0, readCount).SequenceEqual(referenceContent.AsSpan(Math.Min(referenceContent.Length, fileOffset), expectedCount))); } finally { ArrayPool <byte> .Shared.Return(buffer); } } }