Example #1
0
        /// <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);
Example #4
0
        /// <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);
        }
Example #5
0
            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
        }
Example #7
0
        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);
            }
        }
Example #8
0
        /// <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);
        }
Example #9
0
 /// <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));
Example #10
0
 /// <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);
Example #11
0
 /// <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);
Example #12
0
 /// <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());
Example #13
0
 /// <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);
Example #14
0
 /// <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);
Example #16
0
 /// <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);
     }