Skip to content

Commit dacb713

Browse files
committed
Add test cases for tiled tiff, deflate compressed with predictor and color type Rgb323232
1 parent f804ca2 commit dacb713

File tree

5 files changed

+100
-58
lines changed

5 files changed

+100
-58
lines changed

src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs

Lines changed: 90 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
7272
case TiffColorType.PaletteColor:
7373
UndoGray8BitRow(pixelBytes, width, y);
7474
break;
75+
7576
case TiffColorType.BlackIsZero16:
7677
case TiffColorType.WhiteIsZero16:
7778
if (isBigEndian)
@@ -84,6 +85,7 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
8485
}
8586

8687
break;
88+
8789
case TiffColorType.BlackIsZero32:
8890
case TiffColorType.WhiteIsZero32:
8991
if (isBigEndian)
@@ -96,14 +98,17 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
9698
}
9799

98100
break;
101+
99102
case TiffColorType.Rgb888:
100103
case TiffColorType.CieLab:
101104
UndoRgb24BitRow(pixelBytes, width, y);
102105
break;
106+
103107
case TiffColorType.Rgba8888:
104108
case TiffColorType.Cmyk:
105109
UndoRgba32BitRow(pixelBytes, width, y);
106110
break;
111+
107112
case TiffColorType.Rgb161616:
108113
if (isBigEndian)
109114
{
@@ -115,6 +120,7 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
115120
}
116121

117122
break;
123+
118124
case TiffColorType.Rgba16161616:
119125
if (isBigEndian)
120126
{
@@ -125,6 +131,18 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
125131
UndoRgb64BitLittleEndianRow(pixelBytes, width, y);
126132
}
127133

134+
break;
135+
136+
case TiffColorType.Rgb323232:
137+
if (isBigEndian)
138+
{
139+
UndoRgb96BitBigEndianRow(pixelBytes, width, y);
140+
}
141+
else
142+
{
143+
UndoRgb96BitLittleEndianRow(pixelBytes, width, y);
144+
}
145+
128146
break;
129147
}
130148
}
@@ -621,6 +639,76 @@ private static void UndoRgba64Bit(Span<byte> pixelBytes, int width, bool isBigEn
621639
}
622640
}
623641

642+
private static void UndoRgb96BitBigEndianRow(Span<byte> pixelBytes, int width, int y)
643+
{
644+
int rowBytesCount = width * 12;
645+
646+
int offset = 0;
647+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
648+
uint r = TiffUtilities.ConvertToUIntBigEndian(rowBytes.Slice(offset, 4));
649+
offset += 4;
650+
uint g = TiffUtilities.ConvertToUIntBigEndian(rowBytes.Slice(offset, 4));
651+
offset += 4;
652+
uint b = TiffUtilities.ConvertToUIntBigEndian(rowBytes.Slice(offset, 4));
653+
offset += 4;
654+
655+
for (int x = 1; x < width; x++)
656+
{
657+
Span<byte> rowSpan = rowBytes.Slice(offset, 4);
658+
uint deltaR = TiffUtilities.ConvertToUIntBigEndian(rowSpan);
659+
r += deltaR;
660+
BinaryPrimitives.WriteUInt32BigEndian(rowSpan, r);
661+
offset += 4;
662+
663+
rowSpan = rowBytes.Slice(offset, 4);
664+
uint deltaG = TiffUtilities.ConvertToUIntBigEndian(rowSpan);
665+
g += deltaG;
666+
BinaryPrimitives.WriteUInt32BigEndian(rowSpan, g);
667+
offset += 4;
668+
669+
rowSpan = rowBytes.Slice(offset, 4);
670+
uint deltaB = TiffUtilities.ConvertToUIntBigEndian(rowSpan);
671+
b += deltaB;
672+
BinaryPrimitives.WriteUInt32BigEndian(rowSpan, b);
673+
offset += 4;
674+
}
675+
}
676+
677+
private static void UndoRgb96BitLittleEndianRow(Span<byte> pixelBytes, int width, int y)
678+
{
679+
int rowBytesCount = width * 12;
680+
681+
int offset = 0;
682+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
683+
uint r = TiffUtilities.ConvertToUIntLittleEndian(rowBytes.Slice(offset, 4));
684+
offset += 4;
685+
uint g = TiffUtilities.ConvertToUIntLittleEndian(rowBytes.Slice(offset, 4));
686+
offset += 4;
687+
uint b = TiffUtilities.ConvertToUIntLittleEndian(rowBytes.Slice(offset, 4));
688+
offset += 4;
689+
690+
for (int x = 1; x < width; x++)
691+
{
692+
Span<byte> rowSpan = rowBytes.Slice(offset, 4);
693+
uint deltaR = TiffUtilities.ConvertToUIntLittleEndian(rowSpan);
694+
r += deltaR;
695+
BinaryPrimitives.WriteUInt32LittleEndian(rowSpan, r);
696+
offset += 4;
697+
698+
rowSpan = rowBytes.Slice(offset, 4);
699+
uint deltaG = TiffUtilities.ConvertToUIntLittleEndian(rowSpan);
700+
g += deltaG;
701+
BinaryPrimitives.WriteUInt32LittleEndian(rowSpan, g);
702+
offset += 4;
703+
704+
rowSpan = rowBytes.Slice(offset, 4);
705+
uint deltaB = TiffUtilities.ConvertToUIntLittleEndian(rowSpan);
706+
b += deltaB;
707+
BinaryPrimitives.WriteUInt32LittleEndian(rowSpan, b);
708+
offset += 4;
709+
}
710+
}
711+
624712
private static void UndoRgb96Bit(Span<byte> pixelBytes, int width, bool isBigEndian)
625713
{
626714
int rowBytesCount = width * 12;
@@ -629,70 +717,14 @@ private static void UndoRgb96Bit(Span<byte> pixelBytes, int width, bool isBigEnd
629717
{
630718
for (int y = 0; y < height; y++)
631719
{
632-
int offset = 0;
633-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
634-
uint r = TiffUtilities.ConvertToUIntBigEndian(rowBytes.Slice(offset, 4));
635-
offset += 4;
636-
uint g = TiffUtilities.ConvertToUIntBigEndian(rowBytes.Slice(offset, 4));
637-
offset += 4;
638-
uint b = TiffUtilities.ConvertToUIntBigEndian(rowBytes.Slice(offset, 4));
639-
offset += 4;
640-
641-
for (int x = 1; x < width; x++)
642-
{
643-
Span<byte> rowSpan = rowBytes.Slice(offset, 4);
644-
uint deltaR = TiffUtilities.ConvertToUIntBigEndian(rowSpan);
645-
r += deltaR;
646-
BinaryPrimitives.WriteUInt32BigEndian(rowSpan, r);
647-
offset += 4;
648-
649-
rowSpan = rowBytes.Slice(offset, 4);
650-
uint deltaG = TiffUtilities.ConvertToUIntBigEndian(rowSpan);
651-
g += deltaG;
652-
BinaryPrimitives.WriteUInt32BigEndian(rowSpan, g);
653-
offset += 4;
654-
655-
rowSpan = rowBytes.Slice(offset, 4);
656-
uint deltaB = TiffUtilities.ConvertToUIntBigEndian(rowSpan);
657-
b += deltaB;
658-
BinaryPrimitives.WriteUInt32BigEndian(rowSpan, b);
659-
offset += 4;
660-
}
720+
UndoRgb96BitBigEndianRow(pixelBytes, width, y);
661721
}
662722
}
663723
else
664724
{
665725
for (int y = 0; y < height; y++)
666726
{
667-
int offset = 0;
668-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
669-
uint r = TiffUtilities.ConvertToUIntLittleEndian(rowBytes.Slice(offset, 4));
670-
offset += 4;
671-
uint g = TiffUtilities.ConvertToUIntLittleEndian(rowBytes.Slice(offset, 4));
672-
offset += 4;
673-
uint b = TiffUtilities.ConvertToUIntLittleEndian(rowBytes.Slice(offset, 4));
674-
offset += 4;
675-
676-
for (int x = 1; x < width; x++)
677-
{
678-
Span<byte> rowSpan = rowBytes.Slice(offset, 4);
679-
uint deltaR = TiffUtilities.ConvertToUIntLittleEndian(rowSpan);
680-
r += deltaR;
681-
BinaryPrimitives.WriteUInt32LittleEndian(rowSpan, r);
682-
offset += 4;
683-
684-
rowSpan = rowBytes.Slice(offset, 4);
685-
uint deltaG = TiffUtilities.ConvertToUIntLittleEndian(rowSpan);
686-
g += deltaG;
687-
BinaryPrimitives.WriteUInt32LittleEndian(rowSpan, g);
688-
offset += 4;
689-
690-
rowSpan = rowBytes.Slice(offset, 4);
691-
uint deltaB = TiffUtilities.ConvertToUIntLittleEndian(rowSpan);
692-
b += deltaB;
693-
BinaryPrimitives.WriteUInt32LittleEndian(rowSpan, b);
694-
offset += 4;
695-
}
727+
UndoRgb96BitLittleEndianRow(pixelBytes, width, y);
696728
}
697729
}
698730
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public void TiffDecoder_CanDecode_Planar<TPixel>(TestImageProvider<TPixel> provi
9898
[WithFile(TiledRgb48BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9999
[WithFile(TiledRgba64BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
100100
[WithFile(TiledRgba64BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
101+
[WithFile(TiledRgb96BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
102+
[WithFile(TiledRgb96BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
101103
public void TiffDecoder_CanDecode_Tiled<TPixel>(TestImageProvider<TPixel> provider)
102104
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
103105

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,8 @@ public static class Tiff
997997
public const string TiledRgb48BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_big_endian_deflate_compressed_predictor.tiff";
998998
public const string TiledRgba64BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_64bit_little_endian_deflate_compressed_predictor.tiff";
999999
public const string TiledRgba64BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_64bit_big_endian_deflate_compressed_predictor.tiff";
1000+
public const string TiledRgb96BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_96bit_little_endian_deflate_compressed_predictor.tiff";
1001+
public const string TiledRgb96BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_96bit_big_endian_deflate_compressed_predictor.tiff";
10001002

10011003
// Images with alpha channel.
10021004
public const string Rgba2BitUnassociatedAlpha = "Tiff/RgbaUnassociatedAlpha2bit.tiff";
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:67014dc658ced8b9f2a091f6b4e446d19babec2fb7b4bc14f010e570708d4d57
3+
size 209979
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:535c6bc0231ef2510076bb7362412e337d9df4fc5564dc80a67a48a69ce304a9
3+
size 210047

0 commit comments

Comments
 (0)