diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
index 5a5c2b3e51..db349b8b69 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
@@ -25,20 +25,22 @@ internal static class TiffDecoderOptionsParser
/// True, if the image uses tiles. Otherwise the images has strip's.
public static bool VerifyAndParse(this TiffDecoderCore options, ExifProfile exifProfile, TiffFrameMetadata frameMetadata)
{
- IExifValue extraSamplesExifValue = exifProfile.GetValueInternal(ExifTag.ExtraSamples);
- if (extraSamplesExifValue is not null)
+ if (exifProfile.TryGetValue(ExifTag.ExtraSamples, out IExifValue samples))
{
- short[] extraSamples = (short[])extraSamplesExifValue.GetValue();
- if (extraSamples.Length != 1)
+ // We only support a single sample pertaining to alpha data.
+ // Other information is discarded.
+ TiffExtraSampleType sampleType = (TiffExtraSampleType)samples.Value[0];
+ if (sampleType is TiffExtraSampleType.CorelDrawUnassociatedAlphaData)
{
- TiffThrowHelper.ThrowNotSupported("ExtraSamples is only supported with one extra sample for alpha data.");
+ // According to libtiff, this CorelDRAW-specific value indicates unassociated alpha.
+ // Patch required for compatibility with malformed CorelDRAW-generated TIFFs.
+ // https://libtiff.gitlab.io/libtiff/releases/v3.9.0beta.html
+ sampleType = TiffExtraSampleType.UnassociatedAlphaData;
}
- TiffExtraSampleType extraSamplesType = (TiffExtraSampleType)extraSamples[0];
- options.ExtraSamplesType = extraSamplesType;
- if (extraSamplesType is not (TiffExtraSampleType.UnassociatedAlphaData or TiffExtraSampleType.AssociatedAlphaData))
+ if (sampleType is (TiffExtraSampleType.UnassociatedAlphaData or TiffExtraSampleType.AssociatedAlphaData))
{
- TiffThrowHelper.ThrowNotSupported("Decoding Tiff images with ExtraSamples is not supported with UnspecifiedData.");
+ options.ExtraSamplesType = sampleType;
}
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffExtraSampleType.cs b/src/ImageSharp/Formats/Tiff/TiffExtraSampleType.cs
index 484fc993b0..72d56e2c38 100644
--- a/src/ImageSharp/Formats/Tiff/TiffExtraSampleType.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffExtraSampleType.cs
@@ -22,5 +22,11 @@ internal enum TiffExtraSampleType
/// The extra data is unassociated alpha data is transparency information that logically exists independent of an image;
/// it is commonly called a soft matte.
///
- UnassociatedAlphaData = 2
+ UnassociatedAlphaData = 2,
+
+ ///
+ /// A CorelDRAW-specific value observed in damaged files, indicating unassociated alpha.
+ /// Not part of the official TIFF specification; patched in ImageSharp for compatibility.
+ ///
+ CorelDrawUnassociatedAlphaData = 999
}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
index 839334449d..d66a8def41 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
@@ -772,4 +772,9 @@ public void TiffDecoder_Decode_Resize(TestImageProvider provider
testOutputDetails: details,
appendPixelTypeToFileName: false);
}
+
+ [Theory]
+ [WithFile(ExtraSamplesUnspecified, PixelTypes.Rgba32)]
+ public void TiffDecoder_CanDecode_ExtraSamplesUnspecified(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel => TestTiffDecoder(provider);
}
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 5a7c2e66ea..6021de15cc 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -1112,6 +1112,7 @@ public static class Tiff
public const string Issues2587 = "Tiff/Issues/Issue2587.tiff";
public const string JpegCompressedGray0000539558 = "Tiff/Issues/JpegCompressedGray-0000539558.tiff";
public const string Tiled0000023664 = "Tiff/Issues/tiled-0000023664.tiff";
+ public const string ExtraSamplesUnspecified = "Tiff/Issues/ExtraSamplesUnspecified.tif";
public const string SmallRgbDeflate = "Tiff/rgb_small_deflate.tiff";
public const string SmallRgbLzw = "Tiff/rgb_small_lzw.tiff";
diff --git a/tests/Images/Input/Tiff/Issues/ExtraSamplesUnspecified.tif b/tests/Images/Input/Tiff/Issues/ExtraSamplesUnspecified.tif
new file mode 100644
index 0000000000..b5835c1ed8
--- /dev/null
+++ b/tests/Images/Input/Tiff/Issues/ExtraSamplesUnspecified.tif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:71d28f17d2d56481faa4d241fae882eae4f8303c70f85bc3759f6a0c2074979e
+size 1426558