Browse Source

Remove BitsPerSample from TiffFrameMetadata

pull/1553/head
Brian Popow 5 years ago
parent
commit
dcb3e6fa2f
  1. 4
      src/ImageSharp/Formats/Tiff/Constants/TiffPhotometricInterpretation.cs
  2. 16
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs
  3. 17
      src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs
  4. 13
      src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
  5. 51
      src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs
  6. 4
      tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
  7. 25
      tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs

4
src/ImageSharp/Formats/Tiff/Constants/TiffPhotometricInterpretation.cs

@ -9,12 +9,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Constants
public enum TiffPhotometricInterpretation : ushort
{
/// <summary>
/// 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.
/// </summary>
WhiteIsZero = 0,
/// <summary>
/// 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.
/// </summary>
BlackIsZero = 1,

16
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs

@ -9,42 +9,42 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
internal enum TiffColorType
{
/// <summary>
/// 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.
/// </summary>
BlackIsZero,
/// <summary>
/// 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.
/// </summary>
BlackIsZero1,
/// <summary>
/// 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.
/// </summary>
BlackIsZero4,
/// <summary>
/// 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.
/// </summary>
BlackIsZero8,
/// <summary>
/// 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.
/// </summary>
WhiteIsZero,
/// <summary>
/// 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.
/// </summary>
WhiteIsZero1,
/// <summary>
/// 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.
/// </summary>
WhiteIsZero4,
/// <summary>
/// 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.
/// </summary>
WhiteIsZero8,

17
src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs

@ -71,22 +71,5 @@ namespace SixLabors.ImageSharp.Formats.Tiff
return TiffBitsPerSample.Unknown;
}
/// <summary>
/// Gets the bits per pixel for the given bits per sample.
/// </summary>
/// <param name="tiffBitsPerSample">The tiff bits per sample.</param>
/// <returns>Bits per pixel.</returns>
public static int BitsPerPixel(this TiffBitsPerSample tiffBitsPerSample)
{
var bitsPerSample = tiffBitsPerSample.Bits();
int bitsPerPixel = 0;
foreach (var bits in bitsPerSample)
{
bitsPerPixel += bits;
}
return bitsPerPixel;
}
}
}

13
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,
};
}
}

51
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;
}
/// <summary>
/// Gets or sets the number of bits per component.
/// Initializes a new instance of the <see cref="TiffFrameMetadata"/> class.
/// </summary>
public TiffBitsPerSample? BitsPerSample { get; set; }
/// <param name="other">The other tiff frame metadata.</param>
private TiffFrameMetadata(TiffFrameMetadata other) => this.BitsPerPixel = other.BitsPerPixel;
/// <summary>
/// Gets or sets the bits per pixel.
/// </summary>
public TiffBitsPerPixel BitsPerPixel { get; set; }
public TiffBitsPerPixel? BitsPerPixel { get; set; }
/// <summary>
/// Returns a new <see cref="TiffFrameMetadata"/> instance parsed from the given Exif profile.
@ -54,32 +48,31 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <param name="profile">The Exif profile containing tiff frame directory tags.</param>
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)
/// <summary>
/// Gets the bits per pixel for the given bits per sample.
/// </summary>
/// <param name="bitsPerSample">The tiff bits per sample.</param>
/// <returns>Bits per pixel.</returns>
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;
}
/// <inheritdoc/>

4
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<TPixel>(
TestImageProvider<TPixel> provider,
TiffBitsPerPixel bitsPerPixel,
TiffBitsPerPixel? bitsPerPixel,
TiffEncodingMode mode,
TiffCompression compression = TiffCompression.None,
TiffPredictor predictor = TiffPredictor.None,

25
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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> 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);
}
}

Loading…
Cancel
Save