Browse Source

Re-Introduce TiffBitsPerSample

pull/1652/head
Brian Popow 5 years ago
parent
commit
67f7b78293
  1. 40
      src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs
  2. 96
      src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs
  3. 170
      src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs
  4. 2
      src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
  5. 9
      src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs
  6. 4
      tests/ImageSharp.Tests/TestImages.cs

40
src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs

@ -85,16 +85,46 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Constants
/// </summary>
public static readonly ushort[] BitsPerSample1Bit = { 1 };
/// <summary>
/// The bits per sample for images with a 2 color palette.
/// </summary>
public static readonly ushort[] BitsPerSample2Bit = { 2 };
/// <summary>
/// The bits per sample for images with a 4 color palette.
/// </summary>
public static readonly ushort[] BitsPerSample4Bit = { 4 };
/// <summary>
/// The bits per sample for 6 bit gray images.
/// </summary>
public static readonly ushort[] BitsPerSample6Bit = { 6 };
/// <summary>
/// The bits per sample for 8 bit images.
/// </summary>
public static readonly ushort[] BitsPerSample8Bit = { 8 };
/// <summary>
/// The bits per sample for 10 bit gray images.
/// </summary>
public static readonly ushort[] BitsPerSample10Bit = { 10 };
/// <summary>
/// The bits per sample for 12 bit gray images.
/// </summary>
public static readonly ushort[] BitsPerSample12Bit = { 12 };
/// <summary>
/// The bits per sample for 14 bit gray images.
/// </summary>
public static readonly ushort[] BitsPerSample14Bit = { 14 };
/// <summary>
/// The bits per sample for 16 bit gray images.
/// </summary>
public static readonly ushort[] BitsPerSample16Bit = { 16 };
/// <summary>
/// The bits per sample for color images with 2 bits for each color channel.
/// </summary>
@ -115,11 +145,21 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Constants
/// </summary>
public static readonly ushort[] BitsPerSampleRgb10Bit = { 10, 10, 10 };
/// <summary>
/// The bits per sample for color images with 12 bits for each color channel.
/// </summary>
public static readonly ushort[] BitsPerSampleRgb12Bit = { 12, 12, 12 };
/// <summary>
/// The bits per sample for color images with 14 bits for each color channel.
/// </summary>
public static readonly ushort[] BitsPerSampleRgb14Bit = { 14, 14, 14 };
/// <summary>
/// The bits per sample for color images with 14 bits for each color channel.
/// </summary>
public static readonly ushort[] BitsPerSampleRgb16Bit = { 16, 16, 16 };
/// <summary>
/// The list of mimetypes that equate to a tiff.
/// </summary>

96
src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs

@ -0,0 +1,96 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Tiff
{
/// <summary>
/// The number of bits per component.
/// </summary>
public enum TiffBitsPerSample
{
/// <summary>
/// The bits per samples is not known.
/// </summary>
Unknown = 0,
/// <summary>
/// One bit per sample for bicolor images.
/// </summary>
Bit1,
/// <summary>
/// Two bits per sample for grayscale images with 4 different levels of gray or paletted images with a palette of 4 colors.
/// </summary>
Bit2,
/// <summary>
/// Four bits per sample for grayscale images with 16 different levels of gray or paletted images with a palette of 16 colors.
/// </summary>
Bit4,
/// <summary>
/// Six bits per sample for grayscale images.
/// </summary>
Bit6,
/// <summary>
/// Eight bits per sample for grayscale images with 256 different levels of gray or paletted images with a palette of 256 colors.
/// </summary>
Bit8,
/// <summary>
/// Ten bits per sample for grayscale images.
/// </summary>
Bit10,
/// <summary>
/// Twelve bits per sample for grayscale images.
/// </summary>
Bit12,
/// <summary>
/// Fourteen bits per sample for grayscale images.
/// </summary>
Bit14,
/// <summary>
/// Sixteen bits per sample for grayscale images.
/// </summary>
Bit16,
/// <summary>
/// 6 bits per sample, each channel has 2 bits.
/// </summary>
Rgb222,
/// <summary>
/// Twelve bits per sample, each channel has 4 bits.
/// </summary>
Rgb444,
/// <summary>
/// 24 bits per sample, each color channel has 8 Bits.
/// </summary>
Rgb888,
/// <summary>
/// Thirty bits per sample, each channel has 10 bits.
/// </summary>
Rgb101010,
/// <summary>
/// Thirty six bits per sample, each channel has 12 bits.
/// </summary>
Rgb121212,
/// <summary>
/// Forty two bits per sample, each channel has 14 bits.
/// </summary>
Rgb141414,
/// <summary>
/// Forty eight bits per sample, each channel has 16 bits.
/// </summary>
Rgb161616,
}
}

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

@ -0,0 +1,170 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
namespace SixLabors.ImageSharp.Formats.Tiff
{
internal static class TiffBitsPerSampleExtensions
{
/// <summary>
/// Gets the bits per channel array for a given BitsPerSample value, e,g, for RGB888: [8, 8, 8]
/// </summary>
/// <param name="tiffBitsPerSample">The tiff bits per sample.</param>
/// <returns>Bits per sample array.</returns>
public static ushort[] BitsPerChannel(this TiffBitsPerSample tiffBitsPerSample)
{
switch (tiffBitsPerSample)
{
case TiffBitsPerSample.Bit1:
return TiffConstants.BitsPerSample1Bit;
case TiffBitsPerSample.Bit2:
return TiffConstants.BitsPerSample2Bit;
case TiffBitsPerSample.Bit4:
return TiffConstants.BitsPerSample4Bit;
case TiffBitsPerSample.Bit6:
return TiffConstants.BitsPerSample6Bit;
case TiffBitsPerSample.Bit8:
return TiffConstants.BitsPerSample8Bit;
case TiffBitsPerSample.Bit10:
return TiffConstants.BitsPerSample10Bit;
case TiffBitsPerSample.Bit12:
return TiffConstants.BitsPerSample12Bit;
case TiffBitsPerSample.Bit14:
return TiffConstants.BitsPerSample14Bit;
case TiffBitsPerSample.Bit16:
return TiffConstants.BitsPerSample16Bit;
case TiffBitsPerSample.Rgb222:
return TiffConstants.BitsPerSampleRgb2Bit;
case TiffBitsPerSample.Rgb444:
return TiffConstants.BitsPerSampleRgb4Bit;
case TiffBitsPerSample.Rgb888:
return TiffConstants.BitsPerSampleRgb8Bit;
case TiffBitsPerSample.Rgb101010:
return TiffConstants.BitsPerSampleRgb10Bit;
case TiffBitsPerSample.Rgb121212:
return TiffConstants.BitsPerSampleRgb12Bit;
case TiffBitsPerSample.Rgb141414:
return TiffConstants.BitsPerSampleRgb14Bit;
case TiffBitsPerSample.Rgb161616:
return TiffConstants.BitsPerSampleRgb16Bit;
default:
return Array.Empty<ushort>();
}
}
/// <summary>
/// Maps an array of bits per sample to a concrete enum value.
/// </summary>
/// <param name="bitsPerSample">The bits per sample array.</param>
/// <returns>TiffBitsPerSample enum value.</returns>
public static TiffBitsPerSample GetBitsPerSample(this ushort[] bitsPerSample)
{
switch (bitsPerSample.Length)
{
case 3:
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb16Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb16Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb16Bit[0])
{
return TiffBitsPerSample.Rgb161616;
}
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb14Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb14Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb14Bit[0])
{
return TiffBitsPerSample.Rgb141414;
}
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb12Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb12Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb12Bit[0])
{
return TiffBitsPerSample.Rgb121212;
}
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb10Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb10Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb10Bit[0])
{
return TiffBitsPerSample.Rgb101010;
}
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb8Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb8Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb8Bit[0])
{
return TiffBitsPerSample.Rgb888;
}
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb4Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb4Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb4Bit[0])
{
return TiffBitsPerSample.Rgb444;
}
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb2Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb2Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb2Bit[0])
{
return TiffBitsPerSample.Rgb222;
}
break;
case 1:
if (bitsPerSample[0] == TiffConstants.BitsPerSample1Bit[0])
{
return TiffBitsPerSample.Bit1;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample2Bit[0])
{
return TiffBitsPerSample.Bit2;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample4Bit[0])
{
return TiffBitsPerSample.Bit4;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample6Bit[0])
{
return TiffBitsPerSample.Bit6;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample8Bit[0])
{
return TiffBitsPerSample.Bit8;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample10Bit[0])
{
return TiffBitsPerSample.Bit10;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample12Bit[0])
{
return TiffBitsPerSample.Bit12;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample14Bit[0])
{
return TiffBitsPerSample.Bit14;
}
if (bitsPerSample[0] == TiffConstants.BitsPerSample16Bit[0])
{
return TiffBitsPerSample.Bit16;
}
break;
}
return TiffBitsPerSample.Unknown;
}
}
}

2
src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs

@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
options.Predictor = frameMetadata.Predictor ?? TiffPredictor.None;
options.PhotometricInterpretation = frameMetadata.PhotometricInterpretation ?? TiffPhotometricInterpretation.Rgb;
options.BitsPerPixel = frameMetadata.BitsPerPixel != null ? (int)frameMetadata.BitsPerPixel.Value : (int)TiffBitsPerPixel.Bit24;
options.BitsPerSample = frameMetadata.BitsPerSample ?? Array.Empty<ushort>();
options.BitsPerSample = frameMetadata.BitsPerSample != null ? frameMetadata.BitsPerSample?.BitsPerChannel() : Array.Empty<ushort>();
options.ParseColorType(exifProfile);
options.ParseCompression(frameMetadata.Compression, exifProfile);

9
src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <summary>
/// Gets or sets number of bits per component.
/// </summary>
public ushort[] BitsPerSample { get; set; }
public TiffBitsPerSample? BitsPerSample { get; set; }
/// <summary>
/// Gets or sets the compression scheme used on the image data.
@ -77,11 +77,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
if (profile != null)
{
meta.BitsPerSample = profile.GetValue(ExifTag.BitsPerSample)?.Value;
meta.BitsPerPixel = BitsPerPixelFromBitsPerSample(meta.BitsPerSample);
meta.BitsPerSample = profile.GetValue(ExifTag.BitsPerSample) != null ? profile.GetValue(ExifTag.BitsPerSample)?.Value.GetBitsPerSample() : null;
meta.BitsPerPixel = BitsPerPixelFromBitsPerSample(meta.BitsPerSample?.BitsPerChannel());
meta.Compression = (TiffCompression?)profile.GetValue(ExifTag.Compression)?.Value;
meta.PhotometricInterpretation =
(TiffPhotometricInterpretation?)profile.GetValue(ExifTag.PhotometricInterpretation)?.Value;
meta.PhotometricInterpretation = (TiffPhotometricInterpretation?)profile.GetValue(ExifTag.PhotometricInterpretation)?.Value;
meta.Predictor = (TiffPredictor?)profile.GetValue(ExifTag.Predictor)?.Value;
profile.RemoveValue(ExifTag.BitsPerSample);

4
tests/ImageSharp.Tests/TestImages.cs

@ -558,8 +558,6 @@ namespace SixLabors.ImageSharp.Tests
public const string RgbPalette = "Tiff/rgb_palette.tiff";
public const string Rgb4BitPalette = "Tiff/bike_colorpalette_4bit.tiff";
public const string RgbPaletteDeflate = "Tiff/rgb_palette_deflate.tiff";
public const string Flower4BitPalette = "Tiff/flower-palette-04.tiff";
public const string Flower4BitPaletteGray = "Tiff/flower-minisblack-04.tiff";
public const string FlowerRgb161616Contiguous = "Tiff/flower-rgb-contig-16.tiff";
public const string FlowerRgb161616Planar = "Tiff/flower-rgb-planar-16.tiff";
public const string FlowerRgb141414Contiguous = "Tiff/flower-rgb-contig-14.tiff";
@ -573,6 +571,8 @@ namespace SixLabors.ImageSharp.Tests
public const string FlowerRgb222Planar = "Tiff/flower-rgb-planar-02.tiff";
public const string Flower2BitGray = "Tiff/flower-minisblack-02.tiff";
public const string Flower2BitPalette = "Tiff/flower-palette-02.tiff";
public const string Flower4BitPalette = "Tiff/flower-palette-04.tiff";
public const string Flower4BitPaletteGray = "Tiff/flower-minisblack-04.tiff";
public const string Flower6BitGray = "Tiff/flower-minisblack-06.tiff";
public const string Flower8BitGray = "Tiff/flower-minisblack-08.tiff";
public const string Flower10BitGray = "Tiff/flower-minisblack-10.tiff";

Loading…
Cancel
Save