Esempio n. 1
0
        /// <summary>
        /// Uses the specified content writer to create <see cref="TiffFileWriter"/>.
        /// </summary>
        /// <param name="writer">The content writer to use.</param>
        /// <param name="leaveOpen">Whether to leave the content writer open when <see cref="TiffFileWriter"/> is dispsoed.</param>
        /// <param name="useBigTiff">Whether to use BigTIFF format.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that fires if the user has requested to abort this operation.</param>
        /// <returns>The create <see cref="TiffFileWriter"/>.</returns>
        public static async Task <TiffFileWriter> OpenAsync(TiffFileContentReaderWriter writer, bool leaveOpen, bool useBigTiff = false, CancellationToken cancellationToken = default)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            TiffFileContentReaderWriter?disposeInstance = writer;

            byte[] smallBuffer = ArrayPool <byte> .Shared.Rent(SmallBufferSize);

            try
            {
                smallBuffer.AsSpan().Clear();
                await writer.WriteAsync(0, new ArraySegment <byte>(smallBuffer, 0, useBigTiff ? 16 : 8), cancellationToken).ConfigureAwait(false);

                disposeInstance = null;
                return(new TiffFileWriter(writer, leaveOpen, useBigTiff));
            }
            finally
            {
                if (!leaveOpen && !(disposeInstance is null))
                {
                    await disposeInstance.DisposeAsync().ConfigureAwait(false);
                }
            }
        }
Esempio n. 2
0
        internal TiffFileWriter(TiffFileContentReaderWriter writer, bool leaveOpen, bool useBigTiff)
        {
            _writer    = writer ?? throw new ArgumentNullException(nameof(writer));
            _leaveOpen = leaveOpen;

            _position         = useBigTiff ? 16 : 8;
            _useBigTiff       = useBigTiff;
            _requireBigTiff   = false;
            _operationContext = useBigTiff ? TiffOperationContext.BigTIFF : TiffOperationContext.StandardTIFF;
        }
Esempio n. 3
0
        private async Task WriteEntriesAsync(CancellationToken cancellationToken)
        {
            Debug.Assert(_writer != null);
            _entries.Sort(TiffImageFileDirectoryEntryComparer.Instance);

            byte[] buffer = ArrayPool <byte> .Shared.Rent(32);

            try
            {
                TiffFileContentReaderWriter writer = _writer !.InnerWriter;
                long position = _writer.Position;

                if (_writer.UseBigTiff)
                {
                    Unsafe.WriteUnaligned(ref buffer[0], (long)(uint)_entries.Count);
                }
                else
                {
                    Unsafe.WriteUnaligned(ref buffer[0], checked ((ushort)_entries.Count));
                }
                await writer.WriteAsync(position, new ArraySegment <byte>(buffer, 0, _writer.OperationContext.ByteCountOfImageFileDirectoryCountField), cancellationToken).ConfigureAwait(false);

                position = _writer.AdvancePosition(_writer.OperationContext.ByteCountOfImageFileDirectoryCountField);

                foreach (TiffImageFileDirectoryEntry entry in _entries)
                {
                    int bytesWritten = entry.Write(_writer.OperationContext, buffer);
                    await writer.WriteAsync(position, new ArraySegment <byte>(buffer, 0, bytesWritten), cancellationToken).ConfigureAwait(false);

                    position = _writer.AdvancePosition(bytesWritten);
                }

                Unsafe.WriteUnaligned(ref buffer[0], (long)0);

                await writer.WriteAsync(position, new ArraySegment <byte>(buffer, 0, _writer.OperationContext.ByteCountOfValueOffsetField), cancellationToken).ConfigureAwait(false);

                _writer.AdvancePosition(_writer.OperationContext.ByteCountOfValueOffsetField);
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(buffer);
            }
        }