Skip to content

Commit 6174279

Browse files
committed
Fix decoding tiff image with BigEndian + 64 bit / pixel + associated alpha
1 parent 672d788 commit 6174279

9 files changed

+86
-1
lines changed

src/ImageSharp/Formats/Tiff/Utils/TiffUtilities.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@ public static TPixel ColorFromRgba64Premultiplied<TPixel>(ushort r, ushort g, us
4545
return TPixel.FromRgba64(default);
4646
}
4747

48-
return TPixel.FromRgba64(new Rgba64((ushort)(r / a), (ushort)(g / a), (ushort)(b / a), a));
48+
float scale = 65535f / a;
49+
ushort ur = (ushort)(r * scale);
50+
ushort ug = (ushort)(g * scale);
51+
ushort ub = (ushort)(b * scale);
52+
53+
return TPixel.FromRgba64(new Rgba64(ur, ug, ub, a));
4954
}
5055

5156
[MethodImpl(MethodImplOptions.AggressiveInlining)]

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,19 @@ public void TiffDecoder_CanDecode_YccK<TPixel>(TestImageProvider<TPixel> provide
365365
image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.0001F), provider);
366366
}
367367

368+
[Theory]
369+
[WithFile(Issues3031, PixelTypes.Rgba64)]
370+
[WithFile(Rgba16BitAssociatedAlphaBigEndian, PixelTypes.Rgba64)]
371+
[WithFile(Rgba16BitAssociatedAlphaLittleEndian, PixelTypes.Rgba64)]
372+
public void TiffDecoder_CanDecode_64Bit_WithAssociatedAlpha<TPixel>(TestImageProvider<TPixel> provider)
373+
where TPixel : unmanaged, IPixel<TPixel>
374+
{
375+
using Image<TPixel> image = provider.GetImage(TiffDecoder.Instance);
376+
image.DebugSave(provider);
377+
378+
image.CompareToReferenceOutput(ImageComparer.Exact, provider);
379+
}
380+
368381
[Theory]
369382
[WithFile(Issues2454_A, PixelTypes.Rgba32)]
370383
[WithFile(Issues2454_B, PixelTypes.Rgba32)]
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using SixLabors.ImageSharp.Formats.Tiff.Utils;
5+
using SixLabors.ImageSharp.PixelFormats;
6+
7+
namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Utils;
8+
9+
[Trait("Format", "Tiff")]
10+
public class TiffUtilitiesTest
11+
{
12+
[Theory]
13+
[InlineData(0, 0, 0, 0)]
14+
[InlineData(42, 84, 128, 0)]
15+
[InlineData(65535, 65535, 65535, 0)]
16+
public void ColorFromRgba64Premultiplied_WithZeroAlpha_ReturnsDefaultPixel(ushort r, ushort g, ushort b, ushort a)
17+
{
18+
Rgba64 actual = TiffUtilities.ColorFromRgba64Premultiplied<Rgba64>(r, g, b, a);
19+
20+
Assert.Equal(default, actual);
21+
}
22+
23+
[Theory]
24+
[InlineData(65535, 65535, 65535, 65535, 65535, 65535, 65535, 65535)]
25+
[InlineData(32767, 0, 0, 65535, 32767, 0, 0, 65535)]
26+
[InlineData(0, 32767, 0, 65535, 0, 32767, 0, 65535)]
27+
[InlineData(0, 0, 32767, 65535, 0, 0, 32767, 65535)]
28+
public void ColorFromRgba64Premultiplied_WithNoAlpha_ReturnExpectedValues(ushort r, ushort g, ushort b, ushort a, ushort expectedR, ushort expectedG, ushort expectedB, ushort expectedA)
29+
{
30+
Rgba64 actual = TiffUtilities.ColorFromRgba64Premultiplied<Rgba64>(r, g, b, a);
31+
32+
Assert.Equal(new Rgba64(expectedR, expectedG, expectedB, expectedA), actual);
33+
}
34+
35+
[Theory]
36+
[InlineData(32766, 0, 0, 32766, 65535, 0, 0, 32766)] // Red, 50% Alpha
37+
[InlineData(0, 32766, 0, 32766, 0, 65535, 0, 32766)] // Green, 50% Alpha
38+
[InlineData(0, 0, 32766, 32766, 0, 0, 65535, 32766)] // Blue, 50% Alpha
39+
[InlineData(8191, 0, 0, 16383, 32765, 0, 0, 16383)] // Red, 25% Alpha
40+
[InlineData(0, 8191, 0, 16383, 0, 32765, 0, 16383)] // Green, 25% Alpha
41+
[InlineData(0, 0, 8191, 16383, 0, 0, 32765, 16383)] // Blue, 25% Alpha
42+
[InlineData(8191, 0, 0, 0, 0, 0, 0, 0)] // Red, 0% Alpha
43+
[InlineData(0, 8191, 0, 0, 0, 0, 0, 0)] // Green, 0% Alpha
44+
[InlineData(0, 0, 8191, 0, 0, 0, 0, 0)] // Blue, 0% Alpha
45+
public void ColorFromRgba64Premultiplied_WithAlpha_ReturnExpectedValues(ushort r, ushort g, ushort b, ushort a, ushort expectedR, ushort expectedG, ushort expectedB, ushort expectedA)
46+
{
47+
Rgba64 actual = TiffUtilities.ColorFromRgba64Premultiplied<Rgba64>(r, g, b, a);
48+
49+
Assert.Equal(new Rgba64(expectedR, expectedG, expectedB, expectedA), actual);
50+
}
51+
}

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,7 @@ public static class Tiff
11421142
public const string Issues2435 = "Tiff/Issues/Issue2435.tiff";
11431143
public const string Issues2454_A = "Tiff/Issues/Issue2454_A.tif";
11441144
public const string Issues2454_B = "Tiff/Issues/Issue2454_B.tif";
1145+
public const string Issues3031 = "Tiff/Issues/Issue3031.tiff";
11451146
public const string Issues2587 = "Tiff/Issues/Issue2587.tiff";
11461147
public const string Issues2679 = "Tiff/Issues/Issue2679.tiff";
11471148
public const string JpegCompressedGray0000539558 = "Tiff/Issues/JpegCompressedGray-0000539558.tiff";
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:6e4d2db56a1b7fdea09ed65eab1d10a02952821f6662ca77caa44b8c51b30310
3+
size 416

0 commit comments

Comments
 (0)