diff --git a/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs b/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs
index 2327528b0..6fe412b92 100644
--- a/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs
+++ b/src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs
@@ -115,6 +115,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Constants
///
public static readonly ushort[] BitsPerSampleRgb10Bit = { 10, 10, 10 };
+ ///
+ /// The bits per sample for color images with 14 bits for each color channel.
+ ///
+ public static readonly ushort[] BitsPerSampleRgb14Bit = { 14, 14, 14 };
+
///
/// The list of mimetypes that equate to a tiff.
///
diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs
index 9ebf48620..924415850 100644
--- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs
+++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs
@@ -97,6 +97,16 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
DebugGuard.IsTrue(colorMap == null, "colorMap");
return new RgbTiffColor(bitsPerSample);
+ case TiffColorType.Rgb141414:
+ DebugGuard.IsTrue(
+ bitsPerSample.Length == 3
+ && bitsPerSample[0] == 14
+ && bitsPerSample[1] == 14
+ && bitsPerSample[2] == 14,
+ "bitsPerSample");
+ DebugGuard.IsTrue(colorMap == null, "colorMap");
+ return new RgbTiffColor(bitsPerSample);
+
case TiffColorType.PaletteColor:
DebugGuard.NotNull(bitsPerSample, "bitsPerSample");
DebugGuard.NotNull(colorMap, "colorMap");
diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs
index afa86b143..22d819953 100644
--- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs
+++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorType.cs
@@ -78,6 +78,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
///
Rgb101010,
+ ///
+ /// RGB color image with 14 bits for each channel.
+ ///
+ Rgb141414,
+
///
/// RGB Full Color. Planar configuration of data.
///
diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs
index dc1ef0fd6..ab9f3cbec 100644
--- a/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs
@@ -48,5 +48,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// Note: The TiffEncoder does not yet support 10 bits per color channel and will default to 24 bits per pixel instead.
///
Bit30 = 30,
+
+ ///
+ /// 42 bits per pixel. 14 bit for each color channel.
+ ///
+ /// Note: The TiffEncoder does not yet support 14 bits per color channel and will default to 24 bits per pixel instead.
+ ///
+ Bit42 = 42,
}
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs
index 02378ded3..088ef5d6f 100644
--- a/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs
@@ -47,5 +47,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// Thirty bits per sample, each channel has 10 bits.
///
Bit30 = 30,
+
+ ///
+ /// Forty two bits per sample, each channel has 14 bits.
+ ///
+ Bit42 = 42,
}
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs
index 51a5a53a7..ca0f0befc 100644
--- a/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerSampleExtensions.cs
@@ -31,6 +31,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff
return TiffConstants.BitsPerSampleRgb8Bit;
case TiffBitsPerSample.Bit30:
return TiffConstants.BitsPerSampleRgb10Bit;
+ case TiffBitsPerSample.Bit42:
+ return TiffConstants.BitsPerSampleRgb14Bit;
default:
return Array.Empty();
@@ -47,6 +49,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff
switch (bitsPerSample.Length)
{
case 3:
+ if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb14Bit[2] &&
+ bitsPerSample[1] == TiffConstants.BitsPerSampleRgb14Bit[1] &&
+ bitsPerSample[0] == TiffConstants.BitsPerSampleRgb14Bit[0])
+ {
+ return TiffBitsPerSample.Bit42;
+ }
+
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb10Bit[2] &&
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb10Bit[1] &&
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb10Bit[0])
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
index cf6ac6dc7..eeac6a33c 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
@@ -182,6 +182,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{
switch (options.BitsPerSample)
{
+ case TiffBitsPerSample.Bit42:
+ options.ColorType = TiffColorType.Rgb141414;
+ break;
+
case TiffBitsPerSample.Bit30:
options.ColorType = TiffColorType.Rgb101010;
break;
@@ -297,6 +301,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
TiffBitsPerPixel.Bit12 => TiffBitsPerSample.Bit12,
TiffBitsPerPixel.Bit24 => TiffBitsPerSample.Bit24,
TiffBitsPerPixel.Bit30 => TiffBitsPerSample.Bit30,
+ TiffBitsPerPixel.Bit42 => TiffBitsPerSample.Bit42,
_ => throw new NotSupportedException("The bits per pixel are not supported"),
};
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
index edfa215cc..d5137c435 100644
--- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
@@ -322,7 +322,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff
case TiffBitsPerPixel.Bit6:
case TiffBitsPerPixel.Bit12:
case TiffBitsPerPixel.Bit30:
- // Encoding 30, 12 and 6 bits per pixel is not yet supported. Default to 24 bits.
+ case TiffBitsPerPixel.Bit42:
+ // Encoding 42, 30, 12 and 6 bits per pixel is not yet supported. Default to 24 bits.
this.SetEncoderOptions(TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb, compression, TiffPredictor.None);
break;
default:
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
index 0dd8e0e22..02b7f97d9 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
@@ -117,6 +117,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
public void TiffDecoder_CanDecode_30Bit(TestImageProvider provider)
where TPixel : unmanaged, IPixel => TestTiffDecoder(provider);
+ [Theory]
+ [WithFile(FlowerRgb141414Contiguous, PixelTypes.Rgba32)]
+ [WithFile(FlowerRgb141414Planar, PixelTypes.Rgba32)]
+ public void TiffDecoder_CanDecode_42Bit(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel => TestTiffDecoder(provider);
+
[Theory]
[WithFile(GrayscaleDeflateMultistrip, PixelTypes.Rgba32)]
[WithFile(RgbDeflateMultistrip, PixelTypes.Rgba32)]
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
index 19cfc42e4..7c386a6a9 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
@@ -78,6 +78,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
}
[Theory]
+ [InlineData(TiffBitsPerPixel.Bit42)]
[InlineData(TiffBitsPerPixel.Bit30)]
[InlineData(TiffBitsPerPixel.Bit12)]
[InlineData(TiffBitsPerPixel.Bit6)]
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 05045d06a..9471a6393 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -560,6 +560,8 @@ namespace SixLabors.ImageSharp.Tests
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 FlowerRgb141414Contiguous = "Tiff/flower-rgb-contig-14.tiff";
+ public const string FlowerRgb141414Planar = "Tiff/flower-rgb-planar-14.tiff";
public const string FlowerRgb101010Contiguous = "Tiff/flower-rgb-contig-10.tiff";
public const string FlowerRgb101010Planar = "Tiff/flower-rgb-planar-10.tiff";
public const string FlowerRgb444Contiguous = "Tiff/flower-rgb-contig-04.tiff";
diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
index 30c2214b5..dffbeac49 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
@@ -25,10 +25,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
{
}
- public MagickReferenceDecoder(bool validate)
- {
- this.validate = validate;
- }
+ public MagickReferenceDecoder(bool validate) => this.validate = validate;
public static MagickReferenceDecoder Instance { get; } = new MagickReferenceDecoder();
@@ -93,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
FromRgba32Bytes(configuration, data, framePixels);
}
- else if (magicFrame.Depth == 16)
+ else if (magicFrame.Depth == 16 || magicFrame.Depth == 14)
{
ushort[] data = pixels.ToShortArray(PixelMapping.RGBA);
Span bytes = MemoryMarshal.Cast(data.AsSpan());
diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-14.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-14.tiff
new file mode 100644
index 000000000..d4d6a9492
--- /dev/null
+++ b/tests/Images/Input/Tiff/flower-rgb-contig-14.tiff
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a419a8e2f89321501ca8ad70d2a19d37a7bf3a8c2f45c809acc30be59139ae29
+size 16855
diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-14.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-14.tiff
new file mode 100644
index 000000000..2d517268e
--- /dev/null
+++ b/tests/Images/Input/Tiff/flower-rgb-planar-14.tiff
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d28f021d40f53a011053f9644400fee2d29c02f97b4101fec899251125dbb18e
+size 16855