diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffPhotometricInterpretation.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffPhotometricInterpretation.cs index d43ccb408..b39e1003a 100644 --- a/src/ImageSharp/Formats/Tiff/Constants/TiffPhotometricInterpretation.cs +++ b/src/ImageSharp/Formats/Tiff/Constants/TiffPhotometricInterpretation.cs @@ -9,12 +9,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Constants public enum TiffPhotometricInterpretation : ushort { /// - /// Bilevel and grayscale: 0 is imaged as white. The maximum value is imaged as black. + /// Bilevel and grayscale: 0 is imaged as white. The maximum value is imaged as black. /// WhiteIsZero = 0, /// - /// Bilevel and grayscale: 0 is imaged as black. The maximum value is imaged as white. + /// Bilevel and grayscale: 0 is imaged as black. The maximum value is imaged as white. /// BlackIsZero = 1, diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs index a9007b640..484d23163 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs @@ -9,42 +9,42 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation internal enum TiffColorType { /// - /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. + /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. /// BlackIsZero, /// - /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. Optimized implementation for bilevel images. + /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. Optimized implementation for bilevel images. /// BlackIsZero1, /// - /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. Optimized implementation for 4-bit images. + /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. Optimized implementation for 4-bit images. /// BlackIsZero4, /// - /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. Optimized implementation for 8-bit images. + /// Grayscale: 0 is imaged as black. The maximum value is imaged as white. Optimized implementation for 8-bit images. /// BlackIsZero8, /// - /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. + /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. /// WhiteIsZero, /// - /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. Optimized implementation for bilevel images. + /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. Optimized implementation for bilevel images. /// WhiteIsZero1, /// - /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. Optimized implementation for 4-bit images. + /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. Optimized implementation for 4-bit images. /// WhiteIsZero4, /// - /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. Optimized implementation for 8-bit images. + /// Grayscale: 0 is imaged as white. The maximum value is imaged as black. Optimized implementation for 8-bit images. /// WhiteIsZero8, diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs index 33e13d08e..5c4c374be 100644 --- a/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs +++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs @@ -71,22 +71,5 @@ namespace SixLabors.ImageSharp.Formats.Tiff return TiffBitsPerSample.Unknown; } - - /// - /// Gets the bits per pixel for the given bits per sample. - /// - /// The tiff bits per sample. - /// Bits per pixel. - public static int BitsPerPixel(this TiffBitsPerSample tiffBitsPerSample) - { - var bitsPerSample = tiffBitsPerSample.Bits(); - int bitsPerPixel = 0; - foreach (var bits in bitsPerSample) - { - bitsPerPixel += bits; - } - - return bitsPerPixel; - } } } diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs index 9ce9ce8e6..7111f5d36 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs @@ -71,8 +71,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff options.Predictor = predictor; options.PhotometricInterpretation = exifProfile.GetValue(ExifTag.PhotometricInterpretation) != null ? (TiffPhotometricInterpretation)exifProfile.GetValue(ExifTag.PhotometricInterpretation).Value : TiffPhotometricInterpretation.WhiteIsZero; - options.BitsPerSample = entries.BitsPerSample.GetValueOrDefault(); - options.BitsPerPixel = entries.BitsPerSample.GetValueOrDefault().BitsPerPixel(); + options.BitsPerPixel = entries.BitsPerPixel != null ? (int)entries.BitsPerPixel.Value : (int)TiffBitsPerPixel.Bit24; + options.BitsPerSample = GetBitsPerSample(entries.BitsPerPixel); ParseColorType(options, exifProfile); ParseCompression(options, exifProfile); @@ -273,5 +273,14 @@ namespace SixLabors.ImageSharp.Formats.Tiff } } } + + private static TiffBitsPerSample GetBitsPerSample(TiffBitsPerPixel? bitsPerPixel) => bitsPerPixel switch + { + TiffBitsPerPixel.Bit1 => TiffBitsPerSample.Bit1, + TiffBitsPerPixel.Bit4 => TiffBitsPerSample.Bit4, + TiffBitsPerPixel.Bit8 => TiffBitsPerSample.Bit8, + TiffBitsPerPixel.Bit24 => TiffBitsPerSample.Bit24, + _ => TiffBitsPerSample.Bit24, + }; } } diff --git a/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs b/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs index 3594ec388..c21238ad9 100644 --- a/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs +++ b/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Metadata.Profiles.Exif; namespace SixLabors.ImageSharp.Formats.Tiff @@ -18,21 +17,16 @@ namespace SixLabors.ImageSharp.Formats.Tiff { } - private TiffFrameMetadata(TiffFrameMetadata other) - { - this.BitsPerSample = other.BitsPerSample; - this.BitsPerPixel = other.BitsPerPixel; - } - /// - /// Gets or sets the number of bits per component. + /// Initializes a new instance of the class. /// - public TiffBitsPerSample? BitsPerSample { get; set; } + /// The other tiff frame metadata. + private TiffFrameMetadata(TiffFrameMetadata other) => this.BitsPerPixel = other.BitsPerPixel; /// /// Gets or sets the bits per pixel. /// - public TiffBitsPerPixel BitsPerPixel { get; set; } + public TiffBitsPerPixel? BitsPerPixel { get; set; } /// /// Returns a new instance parsed from the given Exif profile. @@ -54,32 +48,31 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// The Exif profile containing tiff frame directory tags. internal static void Parse(TiffFrameMetadata meta, ExifProfile profile) { - if (profile is null) - { - profile = new ExifProfile(); - } + profile ??= new ExifProfile(); - TiffPhotometricInterpretation photometricInterpretation = profile.GetValue(ExifTag.PhotometricInterpretation) != null - ? (TiffPhotometricInterpretation)profile.GetValue(ExifTag.PhotometricInterpretation).Value - : TiffPhotometricInterpretation.WhiteIsZero; + ushort[] bitsPerSample = profile.GetValue(ExifTag.BitsPerSample)?.Value; + meta.BitsPerPixel = BitsPerPixelFromBitsPerSample(bitsPerSample); + } - ushort[] bits = profile.GetValue(ExifTag.BitsPerSample)?.Value; - if (bits == null) + /// + /// Gets the bits per pixel for the given bits per sample. + /// + /// The tiff bits per sample. + /// Bits per pixel. + private static TiffBitsPerPixel BitsPerPixelFromBitsPerSample(ushort[] bitsPerSample) + { + if (bitsPerSample == null) { - if (photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero - || photometricInterpretation == TiffPhotometricInterpretation.BlackIsZero) - { - meta.BitsPerSample = TiffBitsPerSample.Bit1; - } - - meta.BitsPerSample = null; + return TiffBitsPerPixel.Bit24; } - else + + int bitsPerPixel = 0; + foreach (ushort bits in bitsPerSample) { - meta.BitsPerSample = bits.GetBitsPerSample(); + bitsPerPixel += bits; } - meta.BitsPerPixel = (TiffBitsPerPixel)meta.BitsPerSample.GetValueOrDefault().BitsPerPixel(); + return (TiffBitsPerPixel)bitsPerPixel; } /// diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 619c1b5c2..fb8354b18 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -358,7 +358,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.True(output.Height > (int)rowsPerStrip); Assert.True(exifProfileOutput.GetValue(ExifTag.StripOffsets)?.Value.Length > 1); Number[] stripByteCounts = exifProfileOutput.GetValue(ExifTag.StripByteCounts)?.Value; + Assert.NotNull(stripByteCounts); Assert.True(stripByteCounts.Length > 1); + Assert.NotNull(outputMeta.BitsPerPixel); foreach (Number sz in stripByteCounts) { @@ -388,7 +390,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff private static void TestTiffEncoderCore( TestImageProvider provider, - TiffBitsPerPixel bitsPerPixel, + TiffBitsPerPixel? bitsPerPixel, TiffEncodingMode mode, TiffCompression compression = TiffCompression.None, TiffPredictor predictor = TiffPredictor.None, diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index 662c7c1f3..1e96e64fd 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -45,27 +45,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.False(meta.ByteOrder == clone.ByteOrder); } - [Theory] - [WithFile(SampleMetadata, PixelTypes.Rgba32)] - public void TiffFrameMetadata_CloneIsDeep(TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - using (Image image = provider.GetImage(TiffDecoder)) - { - ExifProfile exifProfile = image.Frames.RootFrame.Metadata.ExifProfile; - var meta = TiffFrameMetadata.Parse(exifProfile); - var cloneSameAsSampleMetaData = (TiffFrameMetadata)meta.DeepClone(); - Assert.NotNull(cloneSameAsSampleMetaData); - Assert.Equal(TiffBitsPerSample.Bit4, cloneSameAsSampleMetaData.BitsPerSample); - - var clone = (TiffFrameMetadata)meta.DeepClone(); - - clone.BitsPerSample = TiffBitsPerSample.Bit1; - - Assert.False(meta.BitsPerSample == clone.BitsPerSample); - } - } - [Theory] [InlineData(Calliphora_BiColorUncompressed, 1)] [InlineData(GrayscaleUncompressed, 8)] @@ -198,10 +177,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff var frameMetaData = TiffFrameMetadata.Parse(exifProfile); Assert.Equal(TiffBitsPerPixel.Bit4, frameMetaData.BitsPerPixel); - - var tiffFrameMetadata = TiffFrameMetadata.Parse(exifProfile); - Assert.NotNull(frameMetaData); - Assert.Equal(TiffBitsPerSample.Bit4, frameMetaData.BitsPerSample); } }