public ValueTask ReadAsync(TiffPoint offset, TiffPixelBufferWriter <TDestination> destination, CancellationToken cancellationToken)
        {
            ITiffPixelBufferWriter <TDestination> destinationWriter = TiffPixelBufferUnsafeMarshal.GetBuffer(destination, out TiffPoint destinationOffset, out TiffSize size);
            TiffPixelBufferWriter <TSource>       newDestination    = new TiffPassthroughPixelBufferWriter <TSource, TDestination>(destinationWriter).AsPixelBufferWriter().Crop(destinationOffset, size);

            return(_source.ReadAsync(offset, newDestination, cancellationToken));
        }
Exemple #2
0
        public ValueTask ReadAsync(TiffPoint offset, TiffPixelBufferWriter <TTiffPixel> destination, CancellationToken cancellationToken)
        {
            ITiffPixelBufferWriter <TTiffPixel>      destinationWriter = TiffPixelBufferUnsafeMarshal.GetBuffer(destination, out TiffPoint destinationOffset, out TiffSize size);
            TiffPixelBufferWriter <TImageSharpPixel> newDestination    = new ImageSharpConversionPixelBufferWriter <TImageSharpPixel, TIntermediate, TTiffPixel>(destinationWriter).AsPixelBufferWriter().Crop(destinationOffset, size);

            return(_source.ReadAsync(offset, newDestination, cancellationToken));
        }
Exemple #3
0
 /// <summary>
 /// Crop a sub region from <paramref name="writer"/>.
 /// </summary>
 /// <typeparam name="TPixel">The pixel type.</typeparam>
 /// <param name="writer">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 TiffPixelBufferWriter <TPixel> Crop <TPixel>(this ITiffPixelBufferWriter <TPixel> writer, TiffPoint offset, TiffSize size) where TPixel : unmanaged
 {
     if (writer is TiffPixelBufferWriter <TPixel> structWriter)
     {
         return(structWriter.Crop(offset, size));
     }
     return(writer.AsPixelBufferWriter().Crop(offset, size));
 }
Exemple #4
0
 /// <summary>
 /// Wraps <paramref name="writer"/> in <see cref="TiffPixelBufferWriter{TPixel}"/> structure.
 /// </summary>
 /// <typeparam name="TPixel">The pixel type.</typeparam>
 /// <param name="writer">The pixel buffer writer.</param>
 /// <returns>A <see cref="TiffPixelBufferWriter{TPixel}"/> wrapping <paramref name="writer"/>.</returns>
 public static TiffPixelBufferWriter <TPixel> AsPixelBufferWriter <TPixel>(this ITiffPixelBufferWriter <TPixel> writer) where TPixel : unmanaged
 {
     if (writer is TiffPixelBufferWriter <TPixel> structWriter)
     {
         return(structWriter);
     }
     return(new TiffPixelBufferWriter <TPixel>(writer));
 }
        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 TiffCombinedPixelConverter(ITiffPixelBufferWriter <TDestination> writer, ITiffPixelSpanConverter <TSource, TIntermediate> converter1, ITiffPixelSpanConverter <TIntermediate, TDestination> converter2, bool allowInPlaceConvert = true)
            : base(writer, allowInPlaceConvert && Unsafe.SizeOf <TSource>() == Unsafe.SizeOf <TIntermediate>())
        {
            _converter1        = converter1 ?? throw new ArgumentNullException(nameof(converter1));
            _converter2        = converter2 ?? throw new ArgumentNullException(nameof(converter2));
            _canInPlaceConvert = allowInPlaceConvert && Unsafe.SizeOf <TSource>() == Unsafe.SizeOf <TIntermediate>() && Unsafe.SizeOf <TIntermediate>() == Unsafe.SizeOf <TDestination>();

            // Temparary buffer
            _writer = ArrayPool <byte> .Shared.Rent(writer.Width *Unsafe.SizeOf <TIntermediate>());
        }
Exemple #7
0
        /// <summary>
        /// A function to get destination buffer in the specified pixel format.
        /// </summary>
        public sealed override TiffPixelBufferWriter <TPixel> GetWriter <TPixel>()
        {
            ITiffPixelConverterFactory?pixelConverterFactory = PixelConverterFactory;

            if (pixelConverterFactory is null)
            {
                throw new InvalidOperationException("Failed to acquire PixelConverterFactory");
            }

            ITiffPixelBufferWriter <TDestinationPixel> buffer = TiffPixelBufferUnsafeMarshal.GetBuffer(DestinationWriter, out TiffPoint offset, out TiffSize size);

            return(pixelConverterFactory.CreateConverter <TPixel, TDestinationPixel>(buffer).Crop(offset, size));
        }
        /// <summary>
        /// Converts pixel buffer writer of any pixel format <typeparamref name="TBuffer"/> into <see cref="TiffPixelBufferWriter{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TBuffer">The specified pixel type.</typeparam>
        /// <param name="writer">The writer to be converted.</param>
        /// <returns>The converted writer.</returns>
        public override TiffPixelBufferWriter <TPixel> ConvertWriter <TBuffer>(TiffPixelBufferWriter <TBuffer> writer)
        {
            ITiffPixelConverterFactory?pixelConverterFactory = PixelConverterFactory;

            if (pixelConverterFactory is null)
            {
                throw new InvalidOperationException("Failed to acquire PixelConverterFactory");
            }

            ITiffPixelBufferWriter <TBuffer> innerWriter = TiffPixelBufferUnsafeMarshal.GetBuffer(writer, out TiffPoint offset, out TiffSize size);
            ITiffPixelBufferWriter <TPixel>  converted   = pixelConverterFactory.CreateConverter <TPixel, TBuffer>(innerWriter);

            return(converted.Crop(offset, size));
        }
        /// <summary>
        /// Wraps a <see cref="ITiffPixelBufferWriter{TPixel}"/> and creates <see cref="TiffNoopDisposablePixelBufferWriter{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel type.</typeparam>
        /// <param name="writer">The writer to wrap.</param>
        /// <returns></returns>
        public static ITiffPixelBufferWriter <TPixel> Wrap <TPixel>(ITiffPixelBufferWriter <TPixel> writer) where TPixel : unmanaged
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (writer is TiffNoopDisposablePixelBufferWriter <TPixel> noopWriter)
            {
                return(noopWriter);
            }

            return(new TiffNoopDisposablePixelBufferWriter <TPixel>(writer));
        }
 /// <summary>
 /// Initialize <see cref="TiffPixelBufferWriter{TPixel}"/> to wrap <paramref name="writer"/> and represents the same region as <paramref name="writer"/>.
 /// </summary>
 /// <param name="writer">The pixel buffer writer. If <paramref name="writer"/> is null, <see cref="TiffPixelBufferWriter{TPixel}"/> will be empty and represents an emtry 2-dimensional region.</param>
 public TiffPixelBufferWriter(ITiffPixelBufferWriter <TPixel> writer)
 {
     _writer = writer ?? TiffEmptyPixelBufferWriter <TPixel> .Default;
     if (_writer is TiffPixelBufferWriter <TPixel> structWriter)
     {
         _writer = structWriter._writer;
         _offset = structWriter._offset;
         _size   = structWriter._size;
     }
     else
     {
         _offset = default;
         _size   = new TiffSize(_writer.Width, _writer.Height);
     }
 }
#pragma warning disable CA1816 // CA1816: Call GC.SuppressFinalize correctly
        /// <inheritdoc />
        public void Dispose()
#pragma warning restore CA1816 // CA1816: Call GC.SuppressFinalize correctly
        {
            if (!(_cachedHandle is null))
            {
                _cachedHandle.ReleaseBuffer();
            }
            _cachedHandle = null;

            if (!(_writer is null))
            {
                _writer.Dispose();
            }
            _writer = null;
        }
Exemple #12
0
        /// <summary>
        /// Create <see cref="TiffPixelConverter{TSource, TDestination}"/> and wraps <paramref name="writer"/>.
        /// </summary>
        /// <typeparam name="TSource">The pixel format to convert from.</typeparam>
        /// <typeparam name="TDestination">The pixel format to convert to.</typeparam>
        /// <param name="writer">The writer to be wrapped.</param>
        /// <returns>The created <see cref="TiffPixelConverter{TSource, TDestination}"/>.</returns>
        public ITiffPixelBufferWriter <TSource> CreateConverter <TSource, TDestination>(ITiffPixelBufferWriter <TDestination> writer)
            where TSource : unmanaged
            where TDestination : unmanaged
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (typeof(TSource) == typeof(TDestination))
            {
                return(Unsafe.As <ITiffPixelBufferWriter <TSource> >(writer));
            }

            ITiffPixelConverterFactory?factory = DefaultPixelConverterFactoryCache <TSource, TDestination> .Factory;

            if (factory != null)
            {
                return(factory.CreateConverter <TSource, TDestination>(writer));
            }

            foreach (ConverterFactoryDescriptor item in DefaultPixelConverterFactoryList.Factories)
            {
                if (item.SourceType == typeof(TSource) && item.DestinationType == typeof(TDestination))
                {
                    factory = item.ConverterFactory;
                }
            }

            if (factory is null)
            {
                throw new InvalidOperationException($"No converter from {typeof(TSource).FullName} to {typeof(TDestination).FullName} is found.");
            }

            ITiffPixelBufferWriter <TSource> converter = factory.CreateConverter <TSource, TDestination>(writer);

            if (converter != null)
            {
                DefaultPixelConverterFactoryCache <TSource, TDestination> .Factory = factory;
                return(converter);
            }

            throw new InvalidOperationException($"No converter from {typeof(TSource).FullName} to {typeof(TDestination).FullName} is found.");
        }
 public TiffGray8ToRgb24PixelConverter(ITiffPixelBufferWriter <TiffRgb24> writer) : base(writer)
 {
 }
 public TiffGray8ToGray8ReversedPixelConverter(ITiffPixelBufferWriter <TiffGray8Reversed> writer) : base(writer)
 {
 }
Exemple #15
0
 public TiffBgra64ToGray16PixelConverter(ITiffPixelBufferWriter <TiffGray16> writer) : base(writer)
 {
 }
Exemple #16
0
 public TiffCmyk32ToBgra32PixelConverter(ITiffPixelBufferWriter <TiffBgra32> writer) : base(writer)
 {
 }
Exemple #17
0
 public TiffGray16ToCmyk64PixelConverter(ITiffPixelBufferWriter <TiffCmyk64> writer) : base(writer)
 {
 }
Exemple #18
0
        /// <inheritdoc />
        public override void Decode <TPixel>(TiffPoint offset, TiffSize readSize, TiffPoint destinationOffset, ITiffPixelBufferWriter <TPixel> writer)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            readSize = new TiffSize(Math.Max(0, Math.Min(writer.Width - destinationOffset.X, readSize.Width)), Math.Max(0, Math.Min(writer.Height - destinationOffset.Y, readSize.Height)));
            readSize = new TiffSize(Math.Max(0, Math.Min(Width - offset.X, readSize.Width)), Math.Max(0, Math.Min(Height - offset.Y, readSize.Height)));
            if (readSize.IsAreaEmpty)
            {
                return;
            }

            if (_parameters.ContentSource is null)
            {
                throw new InvalidOperationException("Failed to acquire ContentSource.");
            }

            using TiffFileContentReader reader = TiffSyncFileContentSource.WrapReader(_parameters.ContentSource.OpenReader());
            var context = new TiffDefaultImageDecoderContext <TPixel>()
            {
                MemoryPool            = _parameters.MemoryPool ?? MemoryPool <byte> .Shared,
                CancellationToken     = CancellationToken.None,
                OperationContext      = _parameters.OperationContext,
                ContentReader         = reader,
                SourceImageSize       = _parameters.ImageSize,
                SourceReadOffset      = offset,
                ReadSize              = readSize,
                PixelConverterFactory = _parameters.PixelConverterFactory ?? TiffDefaultPixelConverterFactory.Instance,
                DestinationWriter     = new TiffPixelBufferWriter <TPixel>(TiffNoopDisposablePixelBufferWriter.Wrap(writer)).Crop(destinationOffset, readSize)
            };

            _pipeline.RunAsync(context).AsTask().GetAwaiter().GetResult();
        }
 public TiffCmyk64ToCmyk32PixelConverter(ITiffPixelBufferWriter <TiffCmyk32> writer) : base(writer)
 {
 }
Exemple #20
0
 public TiffBgr24ToRgba32PixelConverter(ITiffPixelBufferWriter <TiffRgba32> writer) : base(writer)
 {
 }
 internal TiffPixelBufferWriter(ITiffPixelBufferWriter <TPixel> writer, TiffPoint offset, TiffSize size)
 {
     _writer = writer;
     _offset = offset;
     _size   = size;
 }
Exemple #22
0
 public TiffRgba64ToBgr24PixelConverter(ITiffPixelBufferWriter <TiffBgr24> writer) : base(writer)
 {
 }
 /// <summary>
 /// Wraps <paramref name="writer"/> as the underlying storage.
 /// </summary>
 /// <param name="writer">The wrapped writer.</param>
 /// <param name="allowInPlaceConvert">If the size of two pixel formats are the same, set this flag to allow conversion to happen on the same buffer without allocating temporary buffer.</param>
 public TiffPixelConverter(ITiffPixelBufferWriter <TDestination> writer, bool allowInPlaceConvert)
 {
     _writer            = writer ?? throw new ArgumentNullException(nameof(writer));
     _canInPlaceConvert = allowInPlaceConvert && Unsafe.SizeOf <TSource>() == Unsafe.SizeOf <TDestination>();
 }
 /// <summary>
 /// Wraps <paramref name="writer"/> as the underlying storage.
 /// </summary>
 /// <param name="writer">The wrapped writer.</param>
 public TiffPixelConverter(ITiffPixelBufferWriter <TDestination> writer) : this(writer, allowInPlaceConvert : Unsafe.SizeOf <TSource>() == Unsafe.SizeOf <TDestination>())
 {
 }
 public ITiffPixelBufferWriter <TSource> CreateConverter <TSource, TDestination>(ITiffPixelBufferWriter <TDestination> buffer)
     where TSource : unmanaged
     where TDestination : unmanaged
 {
     if (typeof(TSource) != typeof(TiffCmyk64) || typeof(TDestination) != typeof(TiffCmyk32))
     {
         throw new InvalidOperationException();
     }
     return(Unsafe.As <ITiffPixelBufferWriter <TSource> >(new TiffCmyk64ToCmyk32PixelConverter(Unsafe.As <ITiffPixelBufferWriter <TiffCmyk32> >(buffer))));
 }
 public TiffMaskToGray8PixelConverter(ITiffPixelBufferWriter <TiffGray8> writer) : base(writer)
 {
 }
Exemple #27
0
 public TiffRgba32ToRgba64PixelConverter(ITiffPixelBufferWriter <TiffRgba64> writer) : base(writer)
 {
 }
 public ITiffPixelBufferWriter <TSource> CreateConverter <TSource, TDestination>(ITiffPixelBufferWriter <TDestination> buffer)
     where TSource : unmanaged
     where TDestination : unmanaged
 {
     if (typeof(TSource) != typeof(TiffMask) || typeof(TDestination) != typeof(TiffGray8))
     {
         throw new InvalidOperationException();
     }
     return(Unsafe.As <ITiffPixelBufferWriter <TSource> >(new TiffPassthroughPixelBufferWriter <TiffMask, TiffGray8>(Unsafe.As <ITiffPixelBufferWriter <TiffGray8> >(buffer))));
 }
Exemple #29
0
        /// <inheritdoc />
        public override async Task DecodeAsync <TPixel>(TiffPoint offset, TiffSize readSize, TiffPoint destinationOffset, ITiffPixelBufferWriter <TPixel> writer, CancellationToken cancellationToken = default)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            readSize = new TiffSize(Math.Max(0, Math.Min(writer.Width - destinationOffset.X, readSize.Width)), Math.Max(0, Math.Min(writer.Height - destinationOffset.Y, readSize.Height)));
            readSize = new TiffSize(Math.Max(0, Math.Min(Width - offset.X, readSize.Width)), Math.Max(0, Math.Min(Height - offset.Y, readSize.Height)));
            if (readSize.IsAreaEmpty)
            {
                return;
            }

            if (_parameters.ContentSource is null)
            {
                throw new InvalidOperationException("Failed to acquire ContentSource.");
            }

            TiffFileContentReader reader = await _parameters.ContentSource.OpenReaderAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                var context = new TiffDefaultImageDecoderContext <TPixel>()
                {
                    MemoryPool            = _parameters.MemoryPool ?? MemoryPool <byte> .Shared,
                    CancellationToken     = cancellationToken,
                    OperationContext      = _parameters.OperationContext,
                    ContentReader         = reader,
                    SourceImageSize       = _parameters.ImageSize,
                    SourceReadOffset      = offset,
                    ReadSize              = readSize,
                    PixelConverterFactory = _parameters.PixelConverterFactory ?? TiffDefaultPixelConverterFactory.Instance,
                    DestinationWriter     = new TiffPixelBufferWriter <TPixel>(TiffNoopDisposablePixelBufferWriter.Wrap(writer)).Crop(destinationOffset, readSize)
                };

                await _pipeline.RunAsync(context).ConfigureAwait(false);
            }
            finally
            {
                await reader.DisposeAsync().ConfigureAwait(false);
            }
        }
Exemple #30
0
 public TiffCmyk64ToBgra64PixelConverter(ITiffPixelBufferWriter <TiffBgra64> writer) : base(writer)
 {
 }