public override void Dispose() { if (_pixelBuffer is null) { return; } // Copy pixels into this column int colIndex = _colIndex; int width = _pixelBuffer.Width; Span <TPixel> sourceSpan = MemoryMarshal.Cast <byte, TPixel>(_buffer.AsSpan(0, _length * Unsafe.SizeOf <TPixel>())); Span <TPixel> destinationSpan = _pixelBuffer.GetSpan().Slice(_start * width); for (int i = 0; i < sourceSpan.Length; i++) { destinationSpan[colIndex + i * width] = sourceSpan[i]; } _pixelBuffer = null; if (_parent != null) { TiffPixelBufferWriterAdapter <TPixel> parent = _parent; _parent = null; if (Interlocked.CompareExchange(ref parent._cachedColHandle, this, null) != null) { ReleaseBuffer(); } } }
internal void SetHandle(TiffPixelBufferWriterAdapter <TPixel> parent, ITiffPixelBuffer <TPixel> buffer, int start, int length) { _parent = parent; _pixelBuffer = buffer; _start = start; _length = length; }
public void TestCrop() { ITiffPixelBuffer <TiffGray8> pixelBuffer = PixelBufferTests.InitializePixelBuffer(out TiffGray8[] pixels); var writer = new TiffPixelBufferWriterAdapter <TiffGray8>(pixelBuffer); TiffPixelBufferWriter <TiffGray8> structWriter = writer.AsPixelBufferWriter(); Assert.Equal(3, structWriter.Width); Assert.Equal(2, structWriter.Height); Assert.False(structWriter.IsEmpty); Assert.Throws <ArgumentOutOfRangeException>("offset", () => structWriter.Crop(new TiffPoint(4, 0))); Assert.Throws <ArgumentOutOfRangeException>("offset", () => structWriter.Crop(new TiffPoint(0, 3))); Assert.Throws <ArgumentOutOfRangeException>("offset", () => structWriter.Crop(new TiffPoint(4, 3))); Assert.Throws <ArgumentOutOfRangeException>("size", () => structWriter.Crop(new TiffPoint(0, 0), new TiffSize(4, 1))); Assert.Throws <ArgumentOutOfRangeException>("size", () => structWriter.Crop(new TiffPoint(0, 0), new TiffSize(1, 3))); Assert.Throws <ArgumentOutOfRangeException>("size", () => structWriter.Crop(new TiffPoint(0, 0), new TiffSize(4, 3))); structWriter = writer.Crop(new TiffPoint(1, 1), new TiffSize(1, 1)); Assert.Equal(1, structWriter.Width); Assert.Equal(1, structWriter.Height); structWriter = writer.AsPixelBufferWriter().Crop(new TiffPoint(1, 1), new TiffSize(1, 1)); Assert.Equal(1, structWriter.Width); Assert.Equal(1, structWriter.Height); structWriter = writer.Crop(new TiffPoint(1, 1)); Assert.Equal(2, structWriter.Width); Assert.Equal(1, structWriter.Height); structWriter = writer.AsPixelBufferWriter().Crop(new TiffPoint(1, 1)); Assert.Equal(2, structWriter.Width); Assert.Equal(1, structWriter.Height); Assert.Throws <ArgumentOutOfRangeException>("rowIndex", () => structWriter.GetRowSpan(-1, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>("rowIndex", () => structWriter.GetRowSpan(2, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => structWriter.GetRowSpan(0, -1, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => structWriter.GetRowSpan(0, 3, 1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => structWriter.GetRowSpan(0, 1, -1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => structWriter.GetRowSpan(0, 1, 2)); Assert.Throws <ArgumentOutOfRangeException>("colIndex", () => structWriter.GetColumnSpan(-1, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>("colIndex", () => structWriter.GetColumnSpan(2, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => structWriter.GetColumnSpan(0, -1, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => structWriter.GetColumnSpan(0, 2, 1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => structWriter.GetColumnSpan(0, 1, -1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => structWriter.GetColumnSpan(0, 1, 2)); ITiffPixelBufferWriter <TiffGray8> writer2 = TiffPixelBufferUnsafeMarshal.GetBuffer(structWriter, out TiffPoint offset, out TiffSize size); Assert.True(ReferenceEquals(writer, writer2)); Assert.Equal(1, offset.X); Assert.Equal(1, offset.Y); Assert.Equal(2, size.Width); Assert.Equal(1, size.Height); }
public void TestWriterAdapter() { Assert.Throws <ArgumentNullException>("buffer", () => new TiffPixelBufferWriterAdapter <TiffGray8>(null)); ITiffPixelBuffer <TiffGray8> pixelBuffer = PixelBufferTests.InitializePixelBuffer(out TiffGray8[] pixels); var writer = new TiffPixelBufferWriterAdapter <TiffGray8>(pixelBuffer); Assert.Equal(3, writer.Width); Assert.Equal(2, writer.Height); }
internal void SetHandle(TiffPixelBufferWriterAdapter <TPixel> parent, ITiffPixelBuffer <TPixel> buffer, int colIndex, int start, int length) { _parent = parent; _pixelBuffer = buffer; _colIndex = colIndex; _start = start; _length = length; EnsureBufferSize(_length * Unsafe.SizeOf <TPixel>()); }
public override void Dispose() { _pixelBuffer = null; if (_parent != null) { TiffPixelBufferWriterAdapter <TPixel> parent = _parent; _parent = null; Interlocked.CompareExchange(ref parent._cachedRowHandle, this, null); } }
/// <summary> /// Decode the image into the specified pixel buffer. /// </summary> /// <typeparam name="TPixel">The pixel type.</typeparam> /// <param name="decoder">The image decoder.</param> /// <param name="buffer">The pixel buffer to write pixels into.</param> public static void Decode <TPixel>(this TiffImageDecoder decoder, TiffPixelBuffer <TPixel> buffer) where TPixel : unmanaged { if (decoder is null) { throw new ArgumentNullException(nameof(decoder)); } if (buffer.IsEmpty) { return; } ITiffPixelBuffer <TPixel> innerBuffer = TiffPixelBufferUnsafeMarshal.GetBuffer(buffer, out TiffPoint offset, out TiffSize size); decoder.Decode(default, size, offset, innerBuffer);
/// <summary> /// Decode the image into the specified pixel buffer. /// </summary> /// <typeparam name="TPixel">The pixel type.</typeparam> /// <param name="decoder">The image decoder.</param> /// <param name="buffer">The pixel buffer to write pixels into.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that fires if the user has requested to abort the decoding pipeline.</param> /// <returns>A <see cref="Task"/> that completes when the image has been decoded.</returns> public static Task DecodeAsync <TPixel>(this TiffImageDecoder decoder, TiffPixelBuffer <TPixel> buffer, CancellationToken cancellationToken = default) where TPixel : unmanaged { if (decoder is null) { throw new ArgumentNullException(nameof(decoder)); } if (buffer.IsEmpty) { return(Task.CompletedTask); } ITiffPixelBuffer <TPixel> innerBuffer = TiffPixelBufferUnsafeMarshal.GetBuffer(buffer, out TiffPoint offset, out TiffSize size); return(decoder.DecodeAsync(default, size, offset, innerBuffer, cancellationToken));
public void TestWriteRows() { ITiffPixelBuffer <TiffGray8> pixelBuffer = PixelBufferTests.InitializePixelBuffer(out TiffGray8[] pixels); var writer = new TiffPixelBufferWriterAdapter <TiffGray8>(pixelBuffer); // Write to first row using (TiffPixelSpanHandle <TiffGray8> pixelSpanHandle = writer.GetRowSpan(0, 0, 1)) { Assert.Equal(1, pixelSpanHandle.Length); Span <TiffGray8> span = pixelSpanHandle.GetSpan(); Assert.Equal(1, span.Length); span[0] = new TiffGray8(0xa1); } // Make sure only the affected pixels are changed while others stay the same. Assert.Equal(0xa1, pixels[0].Intensity); Assert.Equal(0x12, pixels[1].Intensity); Assert.Equal(0x13, pixels[2].Intensity); Assert.Equal(0x21, pixels[3].Intensity); Assert.Equal(0x22, pixels[4].Intensity); Assert.Equal(0x23, pixels[5].Intensity); // Write to second row using (TiffPixelSpanHandle <TiffGray8> pixelSpanHandle = writer.GetRowSpan(1, 1, 2)) { Assert.Equal(2, pixelSpanHandle.Length); Span <TiffGray8> span = pixelSpanHandle.GetSpan(); Assert.Equal(2, span.Length); span[0] = new TiffGray8(0xa2); span[1] = new TiffGray8(0xa3); } // Make sure only the affected pixels are changed while others stay the same. Assert.Equal(0xa1, pixels[0].Intensity); Assert.Equal(0x12, pixels[1].Intensity); Assert.Equal(0x13, pixels[2].Intensity); Assert.Equal(0x21, pixels[3].Intensity); Assert.Equal(0xa2, pixels[4].Intensity); Assert.Equal(0xa3, pixels[5].Intensity); // Failure cases Assert.Throws <ArgumentOutOfRangeException>("rowIndex", () => writer.GetRowSpan(-1, 1, 1)); Assert.Throws <ArgumentOutOfRangeException>("rowIndex", () => writer.GetRowSpan(2, 1, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => writer.GetRowSpan(0, -1, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => writer.GetRowSpan(0, 4, 1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => writer.GetRowSpan(0, 1, -1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => writer.GetRowSpan(0, 1, 3)); }
public void TestWriteOnStructWriter() { ITiffPixelBuffer <TiffGray8> pixelBuffer = PixelBufferTests.InitializePixelBuffer(out TiffGray8[] pixels); var writer = new TiffPixelBufferWriterAdapter <TiffGray8>(pixelBuffer); TiffPixelBufferWriter <TiffGray8> structWriter; structWriter = writer.Crop(new TiffPoint(1, 0), new TiffSize(1, 1)); Assert.Equal(1, structWriter.Width); Assert.Equal(1, structWriter.Height); using (TiffPixelSpanHandle <TiffGray8> pixelSpanHandle = structWriter.GetRowSpan(0, 0, 1)) { Assert.Equal(1, pixelSpanHandle.Length); Span <TiffGray8> span = pixelSpanHandle.GetSpan(); Assert.Equal(1, span.Length); span[0] = new TiffGray8(0xa1); } Assert.Equal(0x11, pixels[0].Intensity); Assert.Equal(0xa1, pixels[1].Intensity); Assert.Equal(0x13, pixels[2].Intensity); Assert.Equal(0x21, pixels[3].Intensity); Assert.Equal(0x22, pixels[4].Intensity); Assert.Equal(0x23, pixels[5].Intensity); using (TiffPixelSpanHandle <TiffGray8> pixelSpanHandle = structWriter.GetColumnSpan(0, 0, 1)) { Assert.Equal(1, pixelSpanHandle.Length); Span <TiffGray8> span = pixelSpanHandle.GetSpan(); Assert.Equal(1, span.Length); span[0] = new TiffGray8(0xa2); } Assert.Equal(0x11, pixels[0].Intensity); Assert.Equal(0xa2, pixels[1].Intensity); Assert.Equal(0x13, pixels[2].Intensity); Assert.Equal(0x21, pixels[3].Intensity); Assert.Equal(0x22, pixels[4].Intensity); Assert.Equal(0x23, pixels[5].Intensity); // Failure cases Assert.Throws <ArgumentOutOfRangeException>("rowIndex", () => structWriter.GetRowSpan(-1, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>("rowIndex", () => structWriter.GetRowSpan(1, 0, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => structWriter.GetRowSpan(0, -1, 1)); Assert.Throws <ArgumentOutOfRangeException>("start", () => structWriter.GetRowSpan(0, 2, 1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => structWriter.GetRowSpan(0, 0, -1)); Assert.Throws <ArgumentOutOfRangeException>("length", () => structWriter.GetRowSpan(0, 0, 2)); }
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); }
/// <summary> /// Wraps <paramref name="buffer"/> in <see cref="TiffPixelBuffer{TPixel}"/> structure. /// </summary> /// <typeparam name="TPixel">The pixel type.</typeparam> /// <param name="buffer">The pixel buffer.</param> /// <returns>A <see cref="TiffPixelBuffer{TPixel}"/> wrapping <paramref name="buffer"/>.</returns> public static TiffPixelBuffer <TPixel> AsPixelBuffer <TPixel>(this ITiffPixelBuffer <TPixel> buffer) where TPixel : unmanaged { return(new TiffPixelBuffer <TPixel>(buffer)); }
/// <summary> /// Initialize the object to wrap <paramref name="buffer"/>. /// </summary> /// <param name="buffer">The pixel buffer to wrap.</param> public TiffPixelBufferReaderAdapter(ITiffPixelBuffer <TPixel> buffer) { _buffer = buffer ?? throw new ArgumentNullException(nameof(buffer)); _size = new TiffSize(buffer.Width, buffer.Height); }
/// <summary> /// Initialize <see cref="TiffPixelBuffer{TPixel}"/> to wrap <paramref name="buffer"/> and represents the same region as <paramref name="buffer"/>. /// </summary> /// <param name="buffer">The pixel buffer. If <paramref name="buffer"/> is null, <see cref="TiffPixelBuffer{TPixel}"/> will be empty and represents an emtry 2-dimensional region.</param> public TiffPixelBuffer(ITiffPixelBuffer <TPixel> buffer) { _buffer = buffer ?? TiffEmptyPixelBuffer <TPixel> .Default; _offset = default; _size = new TiffSize(_buffer.Width, _buffer.Height); }
internal TiffPixelBuffer(ITiffPixelBuffer <TPixel> buffer, TiffPoint offset, TiffSize size) { _buffer = buffer; _offset = offset; _size = size; }
/// <summary> /// Crop a sub region from <paramref name="buffer"/>. /// </summary> /// <typeparam name="TPixel">The pixel type.</typeparam> /// <param name="buffer">The original pixel buffer.</param> /// <param name="offset">The number of columns and rows to skip.</param> /// <param name="size">The number of columns and rows to take.</param> /// <returns>A <see cref="TiffPixelBuffer{TPixel}"/> representing the cropped region.</returns> public static TiffPixelBuffer <TPixel> Crop <TPixel>(this ITiffPixelBuffer <TPixel> buffer, TiffPoint offset, TiffSize size) where TPixel : unmanaged { return(buffer.AsPixelBuffer().Crop(offset, size)); }