Browse Source

Merge pull request #2941 from SixLabors/js/v4-tiff-extra-samples

V4 TIFF : Allow additional and undefined extra samples
pull/2954/head
James Jackson-South 8 months ago
committed by GitHub
parent
commit
a87f5ef130
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 20
      src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
  2. 8
      src/ImageSharp/Formats/Tiff/TiffExtraSampleType.cs
  3. 5
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  4. 1
      tests/ImageSharp.Tests/TestImages.cs
  5. 3
      tests/Images/Input/Tiff/Issues/ExtraSamplesUnspecified.tif

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

@ -25,20 +25,22 @@ internal static class TiffDecoderOptionsParser
/// <returns>True, if the image uses tiles. Otherwise the images has strip's.</returns> /// <returns>True, if the image uses tiles. Otherwise the images has strip's.</returns>
public static bool VerifyAndParse(this TiffDecoderCore options, ExifProfile exifProfile, TiffFrameMetadata frameMetadata) public static bool VerifyAndParse(this TiffDecoderCore options, ExifProfile exifProfile, TiffFrameMetadata frameMetadata)
{ {
IExifValue extraSamplesExifValue = exifProfile.GetValueInternal(ExifTag.ExtraSamples); if (exifProfile.TryGetValue(ExifTag.ExtraSamples, out IExifValue<ushort[]> samples))
if (extraSamplesExifValue is not null)
{ {
short[] extraSamples = (short[])extraSamplesExifValue.GetValue(); // We only support a single sample pertaining to alpha data.
if (extraSamples.Length != 1) // 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]; if (sampleType is (TiffExtraSampleType.UnassociatedAlphaData or TiffExtraSampleType.AssociatedAlphaData))
options.ExtraSamplesType = extraSamplesType;
if (extraSamplesType is not (TiffExtraSampleType.UnassociatedAlphaData or TiffExtraSampleType.AssociatedAlphaData))
{ {
TiffThrowHelper.ThrowNotSupported("Decoding Tiff images with ExtraSamples is not supported with UnspecifiedData."); options.ExtraSamplesType = sampleType;
} }
} }

8
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; /// The extra data is unassociated alpha data is transparency information that logically exists independent of an image;
/// it is commonly called a soft matte. /// it is commonly called a soft matte.
/// </summary> /// </summary>
UnassociatedAlphaData = 2 UnassociatedAlphaData = 2,
/// <summary>
/// A CorelDRAW-specific value observed in damaged files, indicating unassociated alpha.
/// Not part of the official TIFF specification; patched in ImageSharp for compatibility.
/// </summary>
CorelDrawUnassociatedAlphaData = 999,
} }

5
tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs

@ -828,4 +828,9 @@ public class TiffDecoderTests : TiffDecoderBaseTester
testOutputDetails: details, testOutputDetails: details,
appendPixelTypeToFileName: false); appendPixelTypeToFileName: false);
} }
[Theory]
[WithFile(ExtraSamplesUnspecified, PixelTypes.Rgba32)]
public void TiffDecoder_CanDecode_ExtraSamplesUnspecified<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
} }

1
tests/ImageSharp.Tests/TestImages.cs

@ -1136,6 +1136,7 @@ public static class TestImages
public const string Issues2679 = "Tiff/Issues/Issue2679.tiff"; public const string Issues2679 = "Tiff/Issues/Issue2679.tiff";
public const string JpegCompressedGray0000539558 = "Tiff/Issues/JpegCompressedGray-0000539558.tiff"; public const string JpegCompressedGray0000539558 = "Tiff/Issues/JpegCompressedGray-0000539558.tiff";
public const string Tiled0000023664 = "Tiff/Issues/tiled-0000023664.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 SmallRgbDeflate = "Tiff/rgb_small_deflate.tiff";
public const string SmallRgbLzw = "Tiff/rgb_small_lzw.tiff"; public const string SmallRgbLzw = "Tiff/rgb_small_lzw.tiff";

3
tests/Images/Input/Tiff/Issues/ExtraSamplesUnspecified.tif

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:71d28f17d2d56481faa4d241fae882eae4f8303c70f85bc3759f6a0c2074979e
size 1426558
Loading…
Cancel
Save