diff --git a/src/ImageSharp.Formats.Tiff/TiffConstants.cs b/src/ImageSharp.Formats.Tiff/TiffConstants.cs new file mode 100644 index 000000000..e5d2df044 --- /dev/null +++ b/src/ImageSharp.Formats.Tiff/TiffConstants.cs @@ -0,0 +1,30 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Formats +{ + using System.Text; + + /// + /// Defines constants defined in the TIFF specification. + /// + internal static class GifConstants + { + /// + /// Byte order markers for indicating little endian encoding. + /// + public const ushort ByteOrderLittleEndian = 0x4949; + + /// + /// Byte order markers for indicating big endian encoding. + /// + public const ushort ByteOrderBigEndian = 0x4D4D; + + /// + /// Magic number used within the image file header to identify a TIFF format file. + /// + public const ushort HeaderMagicNumber = 42; + } +} diff --git a/src/ImageSharp.Formats.Tiff/TiffFormat.cs b/src/ImageSharp.Formats.Tiff/TiffFormat.cs new file mode 100644 index 000000000..010c54f0a --- /dev/null +++ b/src/ImageSharp.Formats.Tiff/TiffFormat.cs @@ -0,0 +1,41 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Formats +{ + using System.Collections.Generic; + + /// + /// Encapsulates the means to encode and decode Tiff images. + /// + public class TiffFormat //: IImageFormat + { + /// + public string MimeType => "image/tiff"; + + /// + public string Extension => "tif"; + + /// + public IEnumerable SupportedExtensions => new string[] { "tif", "tiff" }; + + /// + //public IImageDecoder Decoder => new TiffDecoder(); + + /// + //public IImageEncoder Encoder => throw new System.NotImplementedException(); + + /// + public int HeaderSize => 4; + + /// + public bool IsSupportedFileFormat(byte[] header) + { + return header.Length >= this.HeaderSize && + ((header[0] == 0x49 && header[1] == 0x49 && header[2] == 0x2A && header[3] == 0x00) || // Little-endian + (header[0] == 0x4D && header[1] == 0x4D && header[2] == 0x00 && header[3] == 0x2A)); // Big-endian + } + } +} diff --git a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs new file mode 100644 index 000000000..313b9c950 --- /dev/null +++ b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs @@ -0,0 +1,88 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests +{ + using System.Linq; + using Xunit; + + using ImageSharp.Formats; + + public class TiffFormatTests + { + public static object[][] IsLittleEndianValues = new[] { new object[] { false }, + new object[] { true } }; + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void IsSupportedFileFormat_ReturnsTrue_ForValidFile(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd() + } + .ToBytes(isLittleEndian); + + TiffFormat tiffFormat = new TiffFormat(); + byte[] headerBytes = bytes.Take(tiffFormat.HeaderSize).ToArray(); + bool isSupported = tiffFormat.IsSupportedFileFormat(headerBytes); + + Assert.True(isSupported); + } + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void IsSupportedFileFormat_ReturnsFalse_WithInvalidByteOrderMarkers(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd(), + ByteOrderMarker = 0x1234 + } + .ToBytes(isLittleEndian); + + TiffFormat tiffFormat = new TiffFormat(); + byte[] headerBytes = bytes.Take(tiffFormat.HeaderSize).ToArray(); + bool isSupported = tiffFormat.IsSupportedFileFormat(headerBytes); + + Assert.False(isSupported); + } + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void IsSupportedFileFormat_ReturnsFalse_WithIncorrectMagicNumber(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd(), + MagicNumber = 32 + } + .ToBytes(isLittleEndian); + + TiffFormat tiffFormat = new TiffFormat(); + byte[] headerBytes = bytes.Take(tiffFormat.HeaderSize).ToArray(); + bool isSupported = tiffFormat.IsSupportedFileFormat(headerBytes); + + Assert.False(isSupported); + } + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void IsSupportedFileFormat_ReturnsFalse_WithShortHeader(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd() + } + .ToBytes(isLittleEndian); + + TiffFormat tiffFormat = new TiffFormat(); + byte[] headerBytes = bytes.Take(tiffFormat.HeaderSize - 1).ToArray(); + bool isSupported = tiffFormat.IsSupportedFileFormat(headerBytes); + + Assert.False(isSupported); + } + } +}