/// <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); } } }
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; }
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); } }