示例#1
0
 internal TiffFieldReader(TiffFileContentReader reader, TiffOperationContext context, bool leaveOpen = false)
 {
     _reader              = reader;
     _context             = context;
     _leaveOpen           = leaveOpen;
     _reverseEndianNeeded = BitConverter.IsLittleEndian != context.IsLittleEndian;
 }
示例#2
0
 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;
     }
 }
示例#3
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();
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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();
            }
        }
示例#6
0
        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);
        }