/// <summary> /// Seek to the specified position. /// </summary> /// <param name="position">The specified position in the stream.</param> public void Seek(TiffStreamOffset position) { EnsureNotDisposed(); long pos = position.ToInt64(); _position = pos; }
public override int Read(TiffStreamOffset offset, ArraySegment <byte> buffer) { TiffFileContentReader?reader = _reader; if (reader is null) { throw new ObjectDisposedException(nameof(SyncContentReader)); } return(reader.Read(offset, buffer)); }
public override int Read(TiffStreamOffset offset, ArraySegment <byte> buffer) { Stream?stream = _stream; if (stream is null) { throw new ObjectDisposedException(nameof(TiffStreamContentReaderWriter)); } if (offset.Offset > stream.Length) { return(default);
/// <summary> /// Writes the IFD into the TIFF stream. /// </summary> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that fires if the user has requested to abort this operation.</param> /// <returns>The offset of the IFD in the stream.</returns> public async Task <TiffStreamOffset> FlushAsync(CancellationToken cancellationToken = default) { EnsureNotDisposed(); cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(_writer != null); await _writer !.AlignToWordBoundaryAsync(cancellationToken).ConfigureAwait(false); TiffStreamOffset position = _writer.Position; await WriteEntriesAsync(cancellationToken).ConfigureAwait(false); return(position); }
public override unsafe int Read(TiffStreamOffset offset, Memory <byte> buffer) { MemoryMappedFile?file = Volatile.Read(ref _file); if (file is null) { throw new ObjectDisposedException(nameof(ContentReader)); } if (offset.Offset + buffer.Length > _capacity) { buffer = buffer.Slice(0, Math.Max(0, (int)(_capacity - offset.Offset))); } if (buffer.IsEmpty) { return(0); } using (MemoryMappedViewAccessor accessor = file.CreateViewAccessor(offset, 0, MemoryMappedFileAccess.Read)) { byte *pointer = null; SafeMemoryMappedViewHandle handle = accessor.SafeMemoryMappedViewHandle; #if !NETSTANDARD1_3 System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try { handle.AcquirePointer(ref pointer); if (pointer != null) { new Span <byte>(pointer + accessor.PointerOffset, buffer.Length).CopyTo(buffer.Span); } return(buffer.Length); } finally { if (pointer != null) { handle.ReleasePointer(); } } } }
public override int Read(TiffStreamOffset offset, Memory <byte> buffer) { Stream?stream = _stream; if (stream is null) { throw new ObjectDisposedException(nameof(TiffStreamContentReaderWriter)); } if (offset.Offset > stream.Length) { return(0); } stream.Seek(offset.Offset, SeekOrigin.Begin); if (MemoryMarshal.TryGetArray(buffer, out ArraySegment <byte> arraySegment)) { if (arraySegment.Array is null) { return(0); } return(stream.Read(arraySegment.Array, arraySegment.Offset, arraySegment.Count)); } #if !NO_FAST_SPAN return(stream.Read(buffer.Span)); #else // Slow path byte[] temp = ArrayPool <byte> .Shared.Rent(buffer.Length); try { int count = stream.Read(temp, 0, buffer.Length); temp.AsMemory(0, count).CopyTo(buffer); return(count); } finally { ArrayPool <byte> .Shared.Return(temp); } #endif }
internal async Task UpdateImageFileDirectoryNextOffsetFieldAsync(TiffStreamOffset target, TiffStreamOffset ifdOffset, CancellationToken cancellationToken) { EnsureNotDisposed(); Debug.Assert(_writer != null); Debug.Assert(_operationContext != null); // Attemps to read 8 bytes even though the size of IFD may be less then 8 bytes. byte[] buffer = ArrayPool <byte> .Shared.Rent(SmallBufferSize); try { int rwCount = await _writer !.ReadAsync(target, new ArraySegment <byte>(buffer, 0, 8), cancellationToken).ConfigureAwait(false); if (!(_useBigTiff && rwCount == 8) && !(!_useBigTiff && rwCount >= 4)) { throw new InvalidDataException(); } int count = ParseImageFileDirectoryCount(buffer.AsSpan(0, 8)); // Prepare next ifd. if (_useBigTiff) { rwCount = 8; long offset = ifdOffset; MemoryMarshal.Write(buffer, ref offset); } else { rwCount = 4; int offset32 = (int)ifdOffset; MemoryMarshal.Write(buffer, ref offset32); } // Skip over IFD entries. int entryFieldLength = _useBigTiff ? 20 : 12; await _writer.WriteAsync(target + _operationContext !.ByteCountOfImageFileDirectoryCountField + count *entryFieldLength, new ArraySegment <byte>(buffer, 0, rwCount), cancellationToken).ConfigureAwait(false); } finally { ArrayPool <byte> .Shared.Return(buffer); } }
/// <summary> /// Writes the IFD into the TIFF stream. Update the specified IFD to point its "Next IFD Offset" field to the IFD just written. /// </summary> /// <param name="previousIfdOffset">The specified IFD to update.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that fires if the user has requested to abort this operation.</param> /// <returns>The offset of the IFD in the stream.</returns> public async Task <TiffStreamOffset> FlushAsync(TiffStreamOffset previousIfdOffset, CancellationToken cancellationToken = default) { EnsureNotDisposed(); cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(_writer != null); await _writer !.AlignToWordBoundaryAsync(cancellationToken).ConfigureAwait(false); TiffStreamOffset position = _writer.Position; await WriteEntriesAsync(cancellationToken).ConfigureAwait(false); if (previousIfdOffset.IsZero) { _writer.SetFirstImageFileDirectoryOffset(position); } else { await _writer.UpdateImageFileDirectoryNextOffsetFieldAsync(previousIfdOffset, position, cancellationToken).ConfigureAwait(false); } return(position); }
/// <summary> /// Read bytes from TIFF file source. /// </summary> /// <param name="offset">The offset in the file.</param> /// <param name="buffer">The buffer to hold bytes.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that fires when the users has requested to stop the IO process.</param> /// <returns>The count of bytes read from file.</returns> public virtual ValueTask <int> ReadAsync(TiffStreamOffset offset, Memory <byte> buffer, CancellationToken cancellationToken = default) => new ValueTask <int>(Read(offset, buffer));
/// <summary> /// Read bytes from TIFF file source. /// </summary> /// <param name="offset">The offset in the file.</param> /// <param name="buffer">The buffer to hold bytes.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that fires when the users has requested to stop the IO process.</param> /// <returns>The count of bytes read from file.</returns> public virtual ValueTask <int> ReadAsync(TiffStreamOffset offset, ArraySegment <byte> buffer, CancellationToken cancellationToken = default) => ReadAsync(offset, buffer.AsMemory(), cancellationToken);
/// <summary> /// Read bytes from TIFF file source. /// </summary> /// <param name="offset">The offset in the file.</param> /// <param name="buffer">The buffer to hold bytes.</param> /// <returns>The count of bytes read from file.</returns> public abstract int Read(TiffStreamOffset offset, Memory <byte> buffer);
/// <summary> /// Read bytes from TIFF file source. /// </summary> /// <param name="offset">The offset in the file.</param> /// <param name="buffer">The buffer to hold bytes.</param> /// <returns>The count of bytes read from file.</returns> public virtual int Read(TiffStreamOffset offset, ArraySegment <byte> buffer) => Read(offset, buffer.AsMemory());
/// <summary> /// Write bytes into TIFF file stream. /// </summary> /// <param name="offset">The offset in the stream.</param> /// <param name="buffer">The buffer to write.</param> public abstract void Write(TiffStreamOffset offset, ReadOnlyMemory <byte> buffer);
/// <summary> /// Write bytes into TIFF file stream. /// </summary> /// <param name="offset">The offset in the stream.</param> /// <param name="buffer">The buffer to write.</param> public virtual void Write(TiffStreamOffset offset, ArraySegment <byte> buffer) => Write(offset, buffer.AsMemory());
public override int Read(TiffStreamOffset offset, ArraySegment <byte> buffer) { if (offset.Offset > _memory.Length) { return(default);
/// <summary> /// Sets the first IFD offset to the specified offset. /// </summary> /// <param name="ifdOffset">The offset of the first IFD.</param> public void SetFirstImageFileDirectoryOffset(TiffStreamOffset ifdOffset) { _imageFileDirectoryOffset = ifdOffset; }
private void AddOrUpdateEntry(TiffTag tag, TiffFieldType type, int count, TiffStreamOffset offset) { if (TryFindEntry(tag, out int i, out _)) { _entries[i] = new TiffImageFileDirectoryEntry(tag, type, count, offset); }