From bace18e4abf5233758e4fc727ca4d6e9343d4a14 Mon Sep 17 00:00:00 2001 From: Andrew Wilkinson Date: Wed, 5 Jul 2017 13:14:38 +0100 Subject: [PATCH] Use new configuration API for TIFF codec --- .../Formats/Tiff/Constants/TiffConstants.cs | 12 ++ .../Formats/Tiff/ITiffDecoderOptions.cs | 18 +++ .../Formats/Tiff/ITiffEncoderOptions.cs | 2 +- .../Formats/Tiff/ImageExtensions.cs | 8 +- .../Formats/Tiff/TiffConfigurationModule.cs | 21 ++++ src/ImageSharp/Formats/Tiff/TiffDecoder.cs | 12 +- .../Formats/Tiff/TiffDecoderCore.cs | 22 ++-- src/ImageSharp/Formats/Tiff/TiffEncoder.cs | 16 +-- .../Formats/Tiff/TiffEncoderCore.cs | 7 +- .../Formats/Tiff/TiffEncoderOptions.cs | 40 ------- src/ImageSharp/Formats/Tiff/TiffFormat.cs | 23 +--- .../Formats/Tiff/TiffImageFormatDetector.cs | 36 ++++++ src/ImageSharp/ImageFormats.cs | 5 + .../Formats/Tiff/TiffDecoderHeaderTests.cs | 6 +- .../Formats/Tiff/TiffDecoderMetadataTests.cs | 4 +- .../Formats/Tiff/TiffFormatTests.cs | 104 +----------------- .../Tiff/TiffImageFormatDetectorTests.cs | 89 +++++++++++++++ .../ImageSharp.Formats.Tiff.Tests.csproj | 2 +- 18 files changed, 227 insertions(+), 200 deletions(-) create mode 100644 src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs create mode 100644 src/ImageSharp/Formats/Tiff/TiffConfigurationModule.cs delete mode 100644 src/ImageSharp/Formats/Tiff/TiffEncoderOptions.cs create mode 100644 src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs create mode 100644 tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffImageFormatDetectorTests.cs diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs index 5c03d33b0c..cd88ccee73 100644 --- a/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs +++ b/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs @@ -5,6 +5,8 @@ namespace ImageSharp.Formats.Tiff { + using System.Collections.Generic; + /// /// Defines constants defined in the TIFF specification. /// @@ -69,5 +71,15 @@ namespace ImageSharp.Formats.Tiff /// Size (in bytes) of the Double data type /// public const int SizeOfDouble = 8; + + /// + /// The list of mimetypes that equate to a tiff. + /// + public static readonly IEnumerable MimeTypes = new[] { "image/tiff", "image/tiff-fx" }; + + /// + /// The list of file extensions that equate to a tiff. + /// + public static readonly IEnumerable FileExtensions = new[] { "tiff", "tif" }; } } diff --git a/src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs b/src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs new file mode 100644 index 0000000000..9f45621349 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/ITiffDecoderOptions.cs @@ -0,0 +1,18 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Formats +{ + /// + /// Encapsulates the options for the . + /// + public interface ITiffDecoderOptions + { + /// + /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. + /// + bool IgnoreMetadata { get; } + } +} diff --git a/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs b/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs index df2ad77709..eefb484c2b 100644 --- a/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs +++ b/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs @@ -8,7 +8,7 @@ namespace ImageSharp.Formats /// /// Encapsulates the options for the . /// - public interface ITiffEncoderOptions : IEncoderOptions + public interface ITiffEncoderOptions { } } diff --git a/src/ImageSharp/Formats/Tiff/ImageExtensions.cs b/src/ImageSharp/Formats/Tiff/ImageExtensions.cs index db160bd9f8..470c09c727 100644 --- a/src/ImageSharp/Formats/Tiff/ImageExtensions.cs +++ b/src/ImageSharp/Formats/Tiff/ImageExtensions.cs @@ -36,16 +36,16 @@ namespace ImageSharp /// The pixel format. /// The image this method extends. /// The stream to save the image to. - /// The options for the encoder. + /// The options for the encoder. /// Thrown if the stream is null. /// /// The . /// - public static Image SaveAsTiff(this Image source, Stream stream, ITiffEncoderOptions options) + public static Image SaveAsTiff(this Image source, Stream stream, TiffEncoder encoder) where TPixel : struct, IPixel { - TiffEncoder encoder = new TiffEncoder(); - encoder.Encode(source, stream, options); + encoder = encoder ?? new TiffEncoder(); + encoder.Encode(source, stream); return source; } diff --git a/src/ImageSharp/Formats/Tiff/TiffConfigurationModule.cs b/src/ImageSharp/Formats/Tiff/TiffConfigurationModule.cs new file mode 100644 index 0000000000..3e280ce839 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/TiffConfigurationModule.cs @@ -0,0 +1,21 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Formats +{ + /// + /// Registers the image encoders, decoders and mime type detectors for the TIFF format. + /// + public sealed class TiffConfigurationModule : IConfigurationModule + { + /// + public void Configure(Configuration host) + { + host.SetEncoder(ImageFormats.Tiff, new TiffEncoder()); + host.SetDecoder(ImageFormats.Tiff, new TiffDecoder()); + host.AddImageFormatDetector(new TiffImageFormatDetector()); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs index 6a605c8782..250b029152 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoder.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoder.cs @@ -6,20 +6,26 @@ namespace ImageSharp.Formats { using System.IO; + using ImageSharp.Formats.Tiff; using ImageSharp.PixelFormats; /// /// Image decoder for generating an image out of a TIFF stream. /// - public class TiffDecoder : IImageDecoder + public class TiffDecoder : IImageDecoder, ITiffDecoderOptions { + /// + /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. + /// + public bool IgnoreMetadata { get; set; } + /// - public Image Decode(Configuration configuration, Stream stream, IDecoderOptions options) + public Image Decode(Configuration configuration, Stream stream) where TPixel : struct, IPixel { Guard.NotNull(stream, "stream"); - using (TiffDecoderCore decoder = new TiffDecoderCore(options, configuration)) + using (TiffDecoderCore decoder = new TiffDecoderCore(configuration, this)) { return decoder.Decode(stream); } diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index d2446bb76d..de42a03457 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -18,24 +18,26 @@ namespace ImageSharp.Formats internal class TiffDecoderCore : IDisposable { /// - /// The decoder options. + /// The global configuration /// - private readonly IDecoderOptions options; + private readonly Configuration configuration; /// - /// The global configuration + /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. /// - private readonly Configuration configuration; + private bool ignoreMetadata; /// /// Initializes a new instance of the class. /// - /// The decoder options. /// The configuration. - public TiffDecoderCore(IDecoderOptions options, Configuration configuration) + /// The decoder options. + public TiffDecoderCore(Configuration configuration, ITiffDecoderOptions options) { + options = options ?? new TiffDecoder(); + this.configuration = configuration ?? Configuration.Default; - this.options = options ?? new DecoderOptions(); + this.ignoreMetadata = options.IgnoreMetadata; } /// @@ -45,8 +47,8 @@ namespace ImageSharp.Formats /// A flag indicating if the file is encoded in little-endian or big-endian format. /// The decoder options. /// The configuration. - public TiffDecoderCore(Stream stream, bool isLittleEndian, IDecoderOptions options, Configuration configuration) - : this(options, configuration) + public TiffDecoderCore(Stream stream, bool isLittleEndian, Configuration configuration, ITiffDecoderOptions options) + : this(configuration, options) { this.InputStream = stream; this.IsLittleEndian = isLittleEndian; @@ -252,7 +254,7 @@ namespace ImageSharp.Formats } } - if (!this.options.IgnoreMetadata) + if (!this.ignoreMetadata) { if (ifd.TryGetIfdEntry(TiffTags.Artist, out TiffIfdEntry artistEntry)) { diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoder.cs b/src/ImageSharp/Formats/Tiff/TiffEncoder.cs index 75ff7dcd4c..6f84bd8523 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoder.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoder.cs @@ -12,28 +12,18 @@ namespace ImageSharp.Formats /// /// Encoder for writing the data image to a stream in TIFF format. /// - public class TiffEncoder : IImageEncoder + public class TiffEncoder : IImageEncoder, ITiffEncoderOptions { - /// - public void Encode(Image image, Stream stream, IEncoderOptions options) - where TPixel : struct, IPixel - { - ITiffEncoderOptions tiffOptions = TiffEncoderOptions.Create(options); - - this.Encode(image, stream, tiffOptions); - } - /// /// Encodes the image to the specified stream from the . /// /// The pixel format. /// The to encode from. /// The to encode the image data to. - /// The options for the encoder. - public void Encode(Image image, Stream stream, ITiffEncoderOptions options) + public void Encode(Image image, Stream stream) where TPixel : struct, IPixel { - var encode = new TiffEncoderCore(options); + var encode = new TiffEncoderCore(this); encode.Encode(image, stream); } } diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index 5f1148adea..d04b221d8b 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -25,18 +25,13 @@ namespace ImageSharp.Formats /// internal sealed class TiffEncoderCore { - /// - /// The options for the encoder. - /// - private readonly ITiffEncoderOptions options; - /// /// Initializes a new instance of the class. /// /// The options for the encoder. public TiffEncoderCore(ITiffEncoderOptions options) { - this.options = options ?? new TiffEncoderOptions(); + options = options ?? new TiffEncoder(); } /// diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderOptions.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderOptions.cs deleted file mode 100644 index 3a9ae8aa22..0000000000 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderOptions.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Formats -{ - /// - /// Encapsulates the options for the . - /// - public sealed class TiffEncoderOptions : EncoderOptions, ITiffEncoderOptions - { - /// - /// Initializes a new instance of the class. - /// - public TiffEncoderOptions() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The options for the encoder. - private TiffEncoderOptions(IEncoderOptions options) - : base(options) - { - } - - /// - /// Converts the options to a instance with a - /// cast or by creating a new instance with the specfied options. - /// - /// The options for the encoder. - /// The options for the . - internal static ITiffEncoderOptions Create(IEncoderOptions options) - { - return options as ITiffEncoderOptions ?? new TiffEncoderOptions(options); - } - } -} diff --git a/src/ImageSharp/Formats/Tiff/TiffFormat.cs b/src/ImageSharp/Formats/Tiff/TiffFormat.cs index 20090a2892..c12134c373 100644 --- a/src/ImageSharp/Formats/Tiff/TiffFormat.cs +++ b/src/ImageSharp/Formats/Tiff/TiffFormat.cs @@ -6,6 +6,7 @@ namespace ImageSharp.Formats { using System.Collections.Generic; + using ImageSharp.Formats.Tiff; /// /// Encapsulates the means to encode and decode Tiff images. @@ -13,29 +14,15 @@ namespace ImageSharp.Formats public class TiffFormat : IImageFormat { /// - public string MimeType => "image/tiff"; + public string Name => "TIFF"; /// - public string Extension => "tif"; + public string DefaultMimeType => "image/tiff"; /// - public IEnumerable SupportedExtensions => new string[] { "tif", "tiff" }; + public IEnumerable MimeTypes => TiffConstants.MimeTypes; /// - public IImageDecoder Decoder => new TiffDecoder(); - - /// - public IImageEncoder Encoder => new TiffEncoder(); - - /// - 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 - } + public IEnumerable FileExtensions => TiffConstants.FileExtensions; } } diff --git a/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs b/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs new file mode 100644 index 0000000000..fd53080f55 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs @@ -0,0 +1,36 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Formats +{ + using System; + + /// + /// Detects tiff file headers + /// + public sealed class TiffImageFormatDetector : IImageFormatDetector + { + /// + public int HeaderSize => 4; + + /// + public IImageFormat DetectFormat(ReadOnlySpan header) + { + if (this.IsSupportedFileFormat(header)) + { + return ImageFormats.Tiff; + } + + return null; + } + + private bool IsSupportedFileFormat(ReadOnlySpan 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 + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/ImageFormats.cs b/src/ImageSharp/ImageFormats.cs index f79191eae6..bc6e0f40f0 100644 --- a/src/ImageSharp/ImageFormats.cs +++ b/src/ImageSharp/ImageFormats.cs @@ -31,5 +31,10 @@ namespace ImageSharp /// The format details for the bitmaps. /// public static readonly IImageFormat Bitmap = new BmpFormat(); + + /// + /// The format details for the tiffs. + /// + public static readonly IImageFormat Tiff = new TiffFormat(); } } \ No newline at end of file diff --git a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderHeaderTests.cs b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderHeaderTests.cs index 0f03c32071..43a349bac5 100644 --- a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderHeaderTests.cs +++ b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderHeaderTests.cs @@ -68,7 +68,7 @@ namespace ImageSharp.Tests TiffDecoder decoder = new TiffDecoder(); - ImageFormatException e = Assert.Throws(() => { decoder.Decode(Configuration.Default, stream, null); }); + ImageFormatException e = Assert.Throws(() => { decoder.Decode(Configuration.Default, stream); }); Assert.Equal("Invalid TIFF file header.", e.Message); } @@ -86,7 +86,7 @@ namespace ImageSharp.Tests TiffDecoder decoder = new TiffDecoder(); - ImageFormatException e = Assert.Throws(() => { decoder.Decode(Configuration.Default, stream, null); }); + ImageFormatException e = Assert.Throws(() => { decoder.Decode(Configuration.Default, stream); }); Assert.Equal("Invalid TIFF file header.", e.Message); } @@ -103,7 +103,7 @@ namespace ImageSharp.Tests TiffDecoder decoder = new TiffDecoder(); - ImageFormatException e = Assert.Throws(() => { decoder.Decode(Configuration.Default, stream, null); }); + ImageFormatException e = Assert.Throws(() => { decoder.Decode(Configuration.Default, stream); }); Assert.Equal("Invalid TIFF file header.", e.Message); } diff --git a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderMetadataTests.cs b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderMetadataTests.cs index ab2ab5f75b..593733f731 100644 --- a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderMetadataTests.cs +++ b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffDecoderMetadataTests.cs @@ -124,8 +124,8 @@ namespace ImageSharp.Tests } .ToStream(isLittleEndian); - DecoderOptions options = new DecoderOptions() { IgnoreMetadata = true }; - TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, options, null); + TiffDecoder options = new TiffDecoder() { IgnoreMetadata = true }; + TiffDecoderCore decoder = new TiffDecoderCore(stream, isLittleEndian, null, options); TiffIfd ifd = decoder.ReadIfd(0); Image image = new Image(null, 20, 20); diff --git a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs index 2657875469..09d90bb197 100644 --- a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs +++ b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffFormatTests.cs @@ -12,110 +12,16 @@ namespace ImageSharp.Tests public class TiffFormatTests { - public static object[][] IsLittleEndianValues = new[] { new object[] { false }, - new object[] { true } }; - [Fact] public void FormatProperties_AreAsExpected() { TiffFormat tiffFormat = new TiffFormat(); - Assert.Equal("image/tiff", tiffFormat.MimeType); - Assert.Equal("tif", tiffFormat.Extension); - Assert.Contains("tif", tiffFormat.SupportedExtensions); - Assert.Contains("tiff", tiffFormat.SupportedExtensions); - } - - [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); - } - - [Fact] - public void Decoder_ReturnsTiffDecoder() - { - TiffFormat tiffFormat = new TiffFormat(); - - var decoder = tiffFormat.Decoder; - - Assert.NotNull(decoder); - Assert.IsType(decoder); - } - - [Fact] - public void Encoder_ReturnsTiffEncoder() - { - TiffFormat tiffFormat = new TiffFormat(); - - var encoder = tiffFormat.Encoder; - - Assert.NotNull(encoder); - Assert.IsType(encoder); + Assert.Equal("TIFF", tiffFormat.Name); + Assert.Equal("image/tiff", tiffFormat.DefaultMimeType); + Assert.Contains("image/tiff", tiffFormat.MimeTypes); + Assert.Contains("tif", tiffFormat.FileExtensions); + Assert.Contains("tiff", tiffFormat.FileExtensions); } } } diff --git a/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffImageFormatDetectorTests.cs b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffImageFormatDetectorTests.cs new file mode 100644 index 0000000000..c7b049e119 --- /dev/null +++ b/tests/ImageSharp.Formats.Tiff.Tests/Formats/Tiff/TiffImageFormatDetectorTests.cs @@ -0,0 +1,89 @@ +// +// 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 TiffImageFormatDetectorTests + { + public static object[][] IsLittleEndianValues = new[] { new object[] { false }, + new object[] { true } }; + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void DetectFormat_ReturnsTiffFormat_ForValidFile(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd() + } + .ToBytes(isLittleEndian); + + TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); + byte[] headerBytes = bytes.Take(formatDetector.HeaderSize).ToArray(); + var format = formatDetector.DetectFormat(headerBytes); + + Assert.NotNull(format); + Assert.IsType(format); + } + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void DetectFormat_ReturnsNull_WithInvalidByteOrderMarkers(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd(), + ByteOrderMarker = 0x1234 + } + .ToBytes(isLittleEndian); + + TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); + byte[] headerBytes = bytes.Take(formatDetector.HeaderSize).ToArray(); + var format = formatDetector.DetectFormat(headerBytes); + + Assert.Null(format); + } + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void DetectFormat_ReturnsNull_WithIncorrectMagicNumber(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd(), + MagicNumber = 32 + } + .ToBytes(isLittleEndian); + + TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); + byte[] headerBytes = bytes.Take(formatDetector.HeaderSize).ToArray(); + var format = formatDetector.DetectFormat(headerBytes); + + Assert.Null(format); + } + + [Theory] + [MemberData(nameof(IsLittleEndianValues))] + public void DetectFormat_ReturnsNull_WithShortHeader(bool isLittleEndian) + { + byte[] bytes = new TiffGenHeader() + { + FirstIfd = new TiffGenIfd() + } + .ToBytes(isLittleEndian); + + TiffImageFormatDetector formatDetector = new TiffImageFormatDetector(); + byte[] headerBytes = bytes.Take(formatDetector.HeaderSize - 1).ToArray(); + var format = formatDetector.DetectFormat(headerBytes); + + Assert.Null(format); + } + } +} diff --git a/tests/ImageSharp.Formats.Tiff.Tests/ImageSharp.Formats.Tiff.Tests.csproj b/tests/ImageSharp.Formats.Tiff.Tests/ImageSharp.Formats.Tiff.Tests.csproj index 8d3d1db362..5ecbcc5b90 100644 --- a/tests/ImageSharp.Formats.Tiff.Tests/ImageSharp.Formats.Tiff.Tests.csproj +++ b/tests/ImageSharp.Formats.Tiff.Tests/ImageSharp.Formats.Tiff.Tests.csproj @@ -7,7 +7,7 @@ - +