internal TiffFieldReader(TiffFileContentReader reader, TiffOperationContext context, bool leaveOpen = false) { _reader = reader; _context = context; _leaveOpen = leaveOpen; _reverseEndianNeeded = BitConverter.IsLittleEndian != context.IsLittleEndian; }
internal TiffImageFileDirectoryEntry(TiffOperationContext context, TiffTag tag, TiffFieldType type, long valueCount, ReadOnlySpan <byte> valueData) { Tag = tag; Type = type; ValueCount = valueCount; if (context.ByteCountOfValueOffsetField == 4) { uint offset32 = MemoryMarshal.Read <uint>(valueData); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { offset32 = BinaryPrimitives.ReverseEndianness(offset32); } ValueOffset = (long)(ulong)offset32; } else if (context.ByteCountOfValueOffsetField == 8) { ulong offset64 = MemoryMarshal.Read <ulong>(valueData); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { offset64 = BinaryPrimitives.ReverseEndianness(offset64); } ValueOffset = (long)offset64; } else { ValueOffset = 0; } }
/// <summary> /// Restore the ValueOffset field into original bytes in the TIFF stream. /// </summary> /// <param name="context">Parameters of how the TIFF file should be parsed.</param> /// <param name="destination">The destination buffer.</param> public void RestoreRawOffsetBytes(TiffOperationContext context, Span <byte> destination) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (destination.Length < context.ByteCountOfValueOffsetField) { throw new ArgumentException($"Destination requires at least {context.ByteCountOfValueOffsetField} bytes.", nameof(destination)); } if (context.ByteCountOfValueOffsetField == 4) { uint valueOffset32 = (uint)ValueOffset; MemoryMarshal.Write(destination, ref valueOffset32); } else { ulong valueOffset64 = (ulong)ValueOffset; MemoryMarshal.Write(destination, ref valueOffset64); } if (context.IsLittleEndian != BitConverter.IsLittleEndian) { destination.Slice(0, context.ByteCountOfValueOffsetField).Reverse(); } }
internal static bool TryParse(TiffOperationContext context, ReadOnlySpan <byte> data, out TiffImageFileDirectoryEntry entry) { if (data.Length < 12) { entry = default; return(false); } ushort tag; short type; tag = MemoryMarshal.Read <ushort>(data); type = MemoryMarshal.Read <short>(data.Slice(2)); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { tag = BinaryPrimitives.ReverseEndianness(tag); type = BinaryPrimitives.ReverseEndianness(type); } data = data.Slice(4); if (context.ByteCountOfValueOffsetField == 4) { uint count32 = MemoryMarshal.Read <uint>(data); uint offset32 = MemoryMarshal.Read <uint>(data.Slice(4)); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { count32 = BinaryPrimitives.ReverseEndianness(count32); offset32 = BinaryPrimitives.ReverseEndianness(offset32); } entry = new TiffImageFileDirectoryEntry((TiffTag)tag, (TiffFieldType)type, (long)(ulong)count32, (long)(ulong)offset32); return(true); } else if (context.ByteCountOfValueOffsetField == 8) { if (data.Length < 16) { entry = default; return(false); } ulong count64 = MemoryMarshal.Read <ulong>(data); ulong offset64 = MemoryMarshal.Read <ulong>(data.Slice(8)); if (context.IsLittleEndian != BitConverter.IsLittleEndian) { count64 = BinaryPrimitives.ReverseEndianness(count64); offset64 = BinaryPrimitives.ReverseEndianness(offset64); } entry = new TiffImageFileDirectoryEntry((TiffTag)tag, (TiffFieldType)type, (long)count64, (long)offset64); return(true); } else { entry = default; return(false); } }
internal int Write(TiffOperationContext context, Span <byte> destination) { if (destination.Length < 12) { throw new ArgumentException("Destination too short.", nameof(destination)); } ushort tag = (ushort)Tag, type = (ushort)Type; if (context.IsLittleEndian != BitConverter.IsLittleEndian) { tag = BinaryPrimitives.ReverseEndianness(tag); type = BinaryPrimitives.ReverseEndianness(type); } MemoryMarshal.Write(destination, ref tag); MemoryMarshal.Write(destination.Slice(2), ref type); destination = destination.Slice(4); if (context.ByteCountOfValueOffsetField == 4) { uint count32 = (uint)ValueCount, offset32 = (uint)ValueOffset; if (context.IsLittleEndian != BitConverter.IsLittleEndian) { count32 = BinaryPrimitives.ReverseEndianness(count32); offset32 = BinaryPrimitives.ReverseEndianness(offset32); } MemoryMarshal.Write(destination, ref count32); MemoryMarshal.Write(destination.Slice(4), ref offset32); return(12); } else if (context.ByteCountOfValueOffsetField == 8) { if (destination.Length < 16) { throw new ArgumentException("Destination too short.", nameof(destination)); } ulong count64 = (ulong)ValueCount, offset64 = (ulong)ValueOffset; if (context.IsLittleEndian != BitConverter.IsLittleEndian) { count64 = BinaryPrimitives.ReverseEndianness(count64); offset64 = BinaryPrimitives.ReverseEndianness(offset64); } MemoryMarshal.Write(destination, ref count64); MemoryMarshal.Write(destination.Slice(8), ref offset64); return(20); } else { throw new NotSupportedException(); } }
internal bool TryDetermineInlined(TiffOperationContext context, out bool isInlined) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (!TryDetermineValueLength(out long bytesLength)) { isInlined = false; return(false); } isInlined = bytesLength <= context.ByteCountOfValueOffsetField; return(true); }