public async Task TestRoundtrip(bool isTile) { TiffGray8[] refImage = new TiffGray8[2048 * 2048]; TiffGray8[] testImage = new TiffGray8[2048 * 2048]; var rand = new Random(42); rand.NextBytes(MemoryMarshal.AsBytes(refImage.AsSpan())); var builder = new TiffImageEncoderBuilder(); builder.PhotometricInterpretation = TiffPhotometricInterpretation.BlackIsZero; builder.Compression = TiffCompression.NoCompression; builder.IsTiled = isTile; // Make sure we have at least CacheSize strips or tiles // Cache size in the current implementation is 256 // Any value greater than 256 should be OK. builder.RowsPerStrip = 2; // 1024 strips builder.TileSize = new TiffSize(16, 16); // 16384 tiles var ms = new MemoryStream(); await GenerateImageAsync(ms, builder, TiffPixelBuffer.WrapReadOnly(refImage, 2048, 2048)); ms.Seek(0, SeekOrigin.Begin); await using TiffFileReader tiff = await TiffFileReader.OpenAsync(ms, leaveOpen : true); TiffImageDecoder decoder = await tiff.CreateImageDecoderAsync(); await decoder.DecodeAsync(TiffPixelBuffer.Wrap(testImage, 2048, 2048)); Assert.True(refImage.AsSpan().SequenceEqual(testImage.AsSpan())); }
public async Task TestAsync(string reference, string test) { using var refImage = Image.Load <L8>(reference); await using TiffFileReader tiff = await TiffFileReader.OpenAsync(test); TiffStreamOffset ifdOffset = tiff.FirstImageFileDirectoryOffset; while (!ifdOffset.IsZero) { TiffImageFileDirectory ifd = await tiff.ReadImageFileDirectoryAsync(ifdOffset); TiffImageDecoder decoder = await tiff.CreateImageDecoderAsync(ifd, new TiffImageDecoderOptions { UndoColorPreMultiplying = true }); Assert.Equal(refImage.Width, decoder.Width); Assert.Equal(refImage.Height, decoder.Height); TiffGray8[] pixels = new TiffGray8[decoder.Width * decoder.Height]; await decoder.DecodeAsync(TiffPixelBuffer.Wrap(pixels, decoder.Width, decoder.Height)); AssertEqual(refImage, pixels); using (var image = new Image <L8>(decoder.Width, decoder.Height)) { decoder.Decode(image); AssertEqual(refImage, image); } ifdOffset = ifd.NextOffset; } }
public void Test(string reference, string test) { using var refImage = Image.Load <Rgb24>(reference); using var tiff = TiffFileReader.Open(test); TiffStreamOffset ifdOffset = tiff.FirstImageFileDirectoryOffset; while (!ifdOffset.IsZero) { TiffImageFileDirectory ifd = tiff.ReadImageFileDirectory(ifdOffset); TiffImageDecoder decoder = tiff.CreateImageDecoder(ifd, new TiffImageDecoderOptions { UndoColorPreMultiplying = true }); Assert.Equal(refImage.Width, decoder.Width); Assert.Equal(refImage.Height, decoder.Height); TiffRgb24[] pixels = new TiffRgb24[decoder.Width * decoder.Height]; decoder.Decode(TiffPixelBuffer.Wrap(pixels, decoder.Width, decoder.Height)); AssertEqual(refImage, pixels); using (var image = new Image <Rgb24>(decoder.Width, decoder.Height)) { decoder.Decode(image); AssertEqual(refImage, image); } ifdOffset = ifd.NextOffset; } }
public async Task TestImageDecodeAsync(string refImage, int refIfd, int refBitDepth, string testImage, int testIfd, int testBitDepth) { const int BufferBitDepth = 16; // We do not support decoding into 32 bit buffer yet. refBitDepth = Math.Min(refBitDepth, BufferBitDepth); testBitDepth = Math.Min(testBitDepth, BufferBitDepth); TiffStreamOffset ifdOffset; TiffImageFileDirectory ifd; // Load reference image await using TiffFileReader refTiff = await TiffFileReader.OpenAsync(refImage); ifdOffset = refTiff.FirstImageFileDirectoryOffset; Assert.False(ifdOffset.IsZero); for (int i = 0; i < refIfd; i++) { ifd = await refTiff.ReadImageFileDirectoryAsync(ifdOffset); ifdOffset = ifd.NextOffset; Assert.False(ifdOffset.IsZero); } ifd = await refTiff.ReadImageFileDirectoryAsync(ifdOffset); TiffImageDecoder refDecoder = await refTiff.CreateImageDecoderAsync(ifd); // Load test image await using TiffFileReader testTiff = await TiffFileReader.OpenAsync(testImage); ifdOffset = testTiff.FirstImageFileDirectoryOffset; Assert.False(ifdOffset.IsZero); for (int i = 0; i < testIfd; i++) { ifd = await testTiff.ReadImageFileDirectoryAsync(ifdOffset); ifdOffset = ifd.NextOffset; Assert.False(ifdOffset.IsZero); } ifd = await testTiff.ReadImageFileDirectoryAsync(ifdOffset); TiffImageDecoder testDecoder = await testTiff.CreateImageDecoderAsync(ifd); Assert.Equal(refDecoder.Width, testDecoder.Width); Assert.Equal(refDecoder.Height, testDecoder.Height); TiffRgba64[] refBuffer = new TiffRgba64[refDecoder.Width * refDecoder.Height]; TiffRgba64[] testBuffer = new TiffRgba64[testDecoder.Width * testDecoder.Height]; await refDecoder.DecodeAsync(TiffPixelBuffer.Wrap(refBuffer, refDecoder.Width, refDecoder.Height)); await testDecoder.DecodeAsync(TiffPixelBuffer.Wrap(testBuffer, testDecoder.Width, testDecoder.Height)); ShiftPixels(MemoryMarshal.Cast <TiffRgba64, ushort>(refBuffer), BufferBitDepth - refBitDepth); ShiftPixels(MemoryMarshal.Cast <TiffRgba64, ushort>(testBuffer), BufferBitDepth - testBitDepth); Assert.True(refBuffer.AsSpan().SequenceEqual(testBuffer)); }
public async Task TestRoundtrip(bool isTile, int maxDegreeOfParallelism, bool isYCbCr) { TiffGray8[] refImage = new TiffGray8[4096 * 4096]; TiffGray8[] testImage = new TiffGray8[4096 * 4096]; var rand = new Random(42); rand.NextBytes(MemoryMarshal.AsBytes(refImage.AsSpan())); var builder = new TiffImageEncoderBuilder(); if (isYCbCr) { builder.PhotometricInterpretation = TiffPhotometricInterpretation.YCbCr; builder.HorizontalChromaSubSampling = 2; builder.VerticalChromaSubSampling = 2; } else { builder.PhotometricInterpretation = TiffPhotometricInterpretation.BlackIsZero; builder.Predictor = TiffPredictor.HorizontalDifferencing; } builder.Compression = TiffCompression.Lzw; builder.IsTiled = isTile; builder.RowsPerStrip = 64; builder.TileSize = new TiffSize(64, 64); builder.MaxDegreeOfParallelism = maxDegreeOfParallelism; var ms = new MemoryStream(); await GenerateImageAsync(ms, builder, TiffPixelBuffer.WrapReadOnly(refImage, 4096, 4096)); ms.Seek(0, SeekOrigin.Begin); await using TiffFileReader tiff = await TiffFileReader.OpenAsync(ms, leaveOpen : true); TiffImageDecoder decoder = await tiff.CreateImageDecoderAsync(); await decoder.DecodeAsync(TiffPixelBuffer.Wrap(testImage, 4096, 4096)); Assert.True(refImage.AsSpan().SequenceEqual(testImage.AsSpan())); }
public void TestMemoryPixelBuffer() { ITiffPixelBuffer <TiffGray8> pixelBuffer = InitializePixelBuffer(out TiffGray8[] pixels); Assert.Equal(3, pixelBuffer.Width); Assert.Equal(2, pixelBuffer.Height); Span <TiffGray8> span = pixelBuffer.GetSpan(); Assert.True(Unsafe.AreSame(ref pixels[0], ref span[0])); Assert.Equal(6, span.Length); span[0] = new TiffGray8(0xCD); span[5] = new TiffGray8(0xEF); Assert.Equal(0xCD, pixels[0].Intensity); Assert.Equal(0xEF, pixels[5].Intensity); Assert.Throws <ArgumentOutOfRangeException>("width", () => TiffPixelBuffer.Wrap(Array.Empty <TiffGray8>(), -1, 0)); Assert.Throws <ArgumentOutOfRangeException>("height", () => TiffPixelBuffer.Wrap(Array.Empty <TiffGray8>(), 0, -1)); }
public void TestCrop() { ITiffPixelBuffer <TiffGray8> pixelBuffer = InitializePixelBuffer(out TiffGray8[] pixels); TiffPixelBuffer <TiffGray8> structBuffer = pixelBuffer.AsPixelBuffer(); Assert.Equal(3, structBuffer.Width); Assert.Equal(2, structBuffer.Height); Assert.False(structBuffer.IsEmpty); Assert.Throws <ArgumentOutOfRangeException>("offset", () => structBuffer.Crop(new TiffPoint(4, 0))); Assert.Throws <ArgumentOutOfRangeException>("offset", () => structBuffer.Crop(new TiffPoint(0, 3))); Assert.Throws <ArgumentOutOfRangeException>("offset", () => structBuffer.Crop(new TiffPoint(4, 3))); Assert.Throws <ArgumentOutOfRangeException>("size", () => structBuffer.Crop(new TiffPoint(0, 0), new TiffSize(4, 1))); Assert.Throws <ArgumentOutOfRangeException>("size", () => structBuffer.Crop(new TiffPoint(0, 0), new TiffSize(1, 3))); Assert.Throws <ArgumentOutOfRangeException>("size", () => structBuffer.Crop(new TiffPoint(0, 0), new TiffSize(4, 3))); structBuffer = pixelBuffer.Crop(new TiffPoint(1, 1), new TiffSize(1, 1)); Assert.Equal(1, structBuffer.Width); Assert.Equal(1, structBuffer.Height); structBuffer = pixelBuffer.AsPixelBuffer().Crop(new TiffPoint(1, 1), new TiffSize(1, 1)); Assert.Equal(1, structBuffer.Width); Assert.Equal(1, structBuffer.Height); structBuffer = pixelBuffer.Crop(new TiffPoint(1, 1)); Assert.Equal(2, structBuffer.Width); Assert.Equal(1, structBuffer.Height); structBuffer = pixelBuffer.AsPixelBuffer().Crop(new TiffPoint(1, 1)); Assert.Equal(2, structBuffer.Width); Assert.Equal(1, structBuffer.Height); ITiffPixelBuffer <TiffGray8> pixelBuffer2 = TiffPixelBufferUnsafeMarshal.GetBuffer(structBuffer, out TiffPoint offset, out TiffSize size); Assert.True(ReferenceEquals(pixelBuffer, pixelBuffer2)); Assert.Equal(1, offset.X); Assert.Equal(1, offset.Y); Assert.Equal(2, size.Width); Assert.Equal(1, size.Height); }
public void Setup() { TiffGray8[] image = new TiffGray8[8192 * 8192]; _image = TiffPixelBuffer.WrapReadOnly(image, 8192, 8192); var builder = new TiffImageEncoderBuilder(); builder.PhotometricInterpretation = TiffPhotometricInterpretation.WhiteIsZero; builder.Compression = Compression; builder.MaxDegreeOfParallelism = DegreeOfParallelism; // Strip encoder builder.IsTiled = false; builder.RowsPerStrip = 256; _stripEncoder = builder.Build <TiffGray8>(); // Tile encoder builder.IsTiled = false; builder.TileSize = new TiffSize(512, 512); _tileEncoder = builder.Build <TiffGray8>(); }
public async Task Setup() { TiffGray8[] image = new TiffGray8[8192 * 8192]; _scratchSpace = TiffPixelBuffer.Wrap(image, 8192, 8192); var builder = new TiffImageEncoderBuilder(); builder.PhotometricInterpretation = TiffPhotometricInterpretation.WhiteIsZero; builder.Compression = Compression; // Generate a image with many strips var ms = new MemoryStream(); builder.IsTiled = false; builder.RowsPerStrip = 256; await GenerateImageAsync(ms, builder, _scratchSpace); _stripTestTiff = ms.ToArray(); ms.SetLength(0); // Generate a image with many tiles builder.IsTiled = true; builder.TileSize = new TiffSize(512, 512); await GenerateImageAsync(ms, builder, _scratchSpace); _tileTestTiff = ms.ToArray(); _stripReader = await TiffFileReader.OpenAsync(_stripTestTiff); _stripDecoder = await _stripReader.CreateImageDecoderAsync(new TiffImageDecoderOptions { MaxDegreeOfParallelism = DegreeOfParallelism }); await _stripDecoder.DecodeAsync(_scratchSpace); _tileReader = await TiffFileReader.OpenAsync(_tileTestTiff); _tileDecoder = await _tileReader.CreateImageDecoderAsync(new TiffImageDecoderOptions { MaxDegreeOfParallelism = DegreeOfParallelism }); await _tileDecoder.DecodeAsync(_scratchSpace); }
public async Task Setup() { TiffGray8[] image = new TiffGray8[8192 * 8192]; _scratchSpace = TiffPixelBuffer.Wrap(image, 8192, 8192); var builder = new TiffImageEncoderBuilder(); builder.PhotometricInterpretation = TiffPhotometricInterpretation.BlackIsZero; builder.Compression = TiffCompression.NoCompression; // Generate a image with many strips var ms = new MemoryStream(); builder.IsTiled = false; builder.RowsPerStrip = 1; await GenerateImageAsync(ms, builder, _scratchSpace); _stripTestTiff = ms.ToArray(); ms.SetLength(0); // Generate a image with many tiles builder.IsTiled = true; builder.TileSize = new TiffSize(16, 16); // the minimum tile size await GenerateImageAsync(ms, builder, _scratchSpace); _tileTestTiff = ms.ToArray(); _stripReader = await TiffFileReader.OpenAsync(_stripTestTiff); _stripDecoder = await _stripReader.CreateImageDecoderAsync(); await _stripDecoder.DecodeAsync(_scratchSpace); _tileReader = await TiffFileReader.OpenAsync(_tileTestTiff); _tileDecoder = await _tileReader.CreateImageDecoderAsync(); await _tileDecoder.DecodeAsync(_scratchSpace); }
private static async Task GenerateImageAsync(Stream stream, TiffImageEncoderBuilder builder, TiffPixelBuffer <TiffGray8> image) { using (TiffFileWriter writer = await TiffFileWriter.OpenAsync(stream, true)) { TiffStreamOffset ifdOffset; using (TiffImageFileDirectoryWriter ifdWriter = writer.CreateImageFileDirectory()) { TiffImageEncoder <TiffGray8> encoder = builder.Build <TiffGray8>(); await encoder.EncodeAsync(ifdWriter, image); ifdOffset = await ifdWriter.FlushAsync(); } writer.SetFirstImageFileDirectoryOffset(ifdOffset); await writer.FlushAsync(); } }