示例#1
0
            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();
                    }
                }
            }
示例#2
0
 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);
        }
示例#5
0
            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>());
            }
示例#6
0
 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);
示例#8
0
        /// <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));
        }
示例#11
0
        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));
        }
示例#12
0
        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);
        }
示例#13
0
 /// <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);
 }
示例#15
0
 /// <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);
 }
示例#16
0
 internal TiffPixelBuffer(ITiffPixelBuffer <TPixel> buffer, TiffPoint offset, TiffSize size)
 {
     _buffer = buffer;
     _offset = offset;
     _size   = size;
 }
示例#17
0
 /// <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));
 }