Skip to content

Commit f804ca2

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

File tree

5 files changed

+109
-74
lines changed

5 files changed

+109
-74
lines changed

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

Lines changed: 99 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
114114
UndoRgb48BitLittleEndianRow(pixelBytes, width, y);
115115
}
116116

117+
break;
118+
case TiffColorType.Rgba16161616:
119+
if (isBigEndian)
120+
{
121+
UndoRgb64BitBigEndianRow(pixelBytes, width, y);
122+
}
123+
else
124+
{
125+
UndoRgb64BitLittleEndianRow(pixelBytes, width, y);
126+
}
127+
117128
break;
118129
}
119130
}
@@ -504,6 +515,92 @@ private static void UndoRgb48Bit(Span<byte> pixelBytes, int width, bool isBigEnd
504515
}
505516
}
506517

518+
private static void UndoRgb64BitBigEndianRow(Span<byte> pixelBytes, int width, int y)
519+
{
520+
int rowBytesCount = width * 8;
521+
int offset = 0;
522+
523+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
524+
ushort r = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
525+
offset += 2;
526+
ushort g = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
527+
offset += 2;
528+
ushort b = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
529+
offset += 2;
530+
ushort a = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
531+
offset += 2;
532+
533+
for (int x = 1; x < width; x++)
534+
{
535+
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
536+
ushort deltaR = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
537+
r += deltaR;
538+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, r);
539+
offset += 2;
540+
541+
rowSpan = rowBytes.Slice(offset, 2);
542+
ushort deltaG = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
543+
g += deltaG;
544+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, g);
545+
offset += 2;
546+
547+
rowSpan = rowBytes.Slice(offset, 2);
548+
ushort deltaB = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
549+
b += deltaB;
550+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, b);
551+
offset += 2;
552+
553+
rowSpan = rowBytes.Slice(offset, 2);
554+
ushort deltaA = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
555+
a += deltaA;
556+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, a);
557+
offset += 2;
558+
}
559+
}
560+
561+
private static void UndoRgb64BitLittleEndianRow(Span<byte> pixelBytes, int width, int y)
562+
{
563+
int rowBytesCount = width * 8;
564+
int offset = 0;
565+
566+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
567+
ushort r = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
568+
offset += 2;
569+
ushort g = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
570+
offset += 2;
571+
ushort b = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
572+
offset += 2;
573+
ushort a = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
574+
offset += 2;
575+
576+
for (int x = 1; x < width; x++)
577+
{
578+
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
579+
ushort deltaR = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
580+
r += deltaR;
581+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, r);
582+
offset += 2;
583+
584+
rowSpan = rowBytes.Slice(offset, 2);
585+
ushort deltaG = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
586+
g += deltaG;
587+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, g);
588+
offset += 2;
589+
590+
rowSpan = rowBytes.Slice(offset, 2);
591+
ushort deltaB = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
592+
b += deltaB;
593+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, b);
594+
offset += 2;
595+
596+
rowSpan = rowBytes.Slice(offset, 2);
597+
ushort deltaA = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
598+
a += deltaA;
599+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, a);
600+
offset += 2;
601+
}
602+
}
603+
507604
private static void UndoRgba64Bit(Span<byte> pixelBytes, int width, bool isBigEndian)
508605
{
509606
int rowBytesCount = width * 8;
@@ -512,86 +609,14 @@ private static void UndoRgba64Bit(Span<byte> pixelBytes, int width, bool isBigEn
512609
{
513610
for (int y = 0; y < height; y++)
514611
{
515-
int offset = 0;
516-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
517-
ushort r = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
518-
offset += 2;
519-
ushort g = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
520-
offset += 2;
521-
ushort b = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
522-
offset += 2;
523-
ushort a = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
524-
offset += 2;
525-
526-
for (int x = 1; x < width; x++)
527-
{
528-
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
529-
ushort deltaR = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
530-
r += deltaR;
531-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, r);
532-
offset += 2;
533-
534-
rowSpan = rowBytes.Slice(offset, 2);
535-
ushort deltaG = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
536-
g += deltaG;
537-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, g);
538-
offset += 2;
539-
540-
rowSpan = rowBytes.Slice(offset, 2);
541-
ushort deltaB = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
542-
b += deltaB;
543-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, b);
544-
offset += 2;
545-
546-
rowSpan = rowBytes.Slice(offset, 2);
547-
ushort deltaA = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
548-
a += deltaA;
549-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, a);
550-
offset += 2;
551-
}
612+
UndoRgb64BitBigEndianRow(pixelBytes, width, y);
552613
}
553614
}
554615
else
555616
{
556617
for (int y = 0; y < height; y++)
557618
{
558-
int offset = 0;
559-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
560-
ushort r = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
561-
offset += 2;
562-
ushort g = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
563-
offset += 2;
564-
ushort b = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
565-
offset += 2;
566-
ushort a = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
567-
offset += 2;
568-
569-
for (int x = 1; x < width; x++)
570-
{
571-
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
572-
ushort deltaR = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
573-
r += deltaR;
574-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, r);
575-
offset += 2;
576-
577-
rowSpan = rowBytes.Slice(offset, 2);
578-
ushort deltaG = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
579-
g += deltaG;
580-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, g);
581-
offset += 2;
582-
583-
rowSpan = rowBytes.Slice(offset, 2);
584-
ushort deltaB = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
585-
b += deltaB;
586-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, b);
587-
offset += 2;
588-
589-
rowSpan = rowBytes.Slice(offset, 2);
590-
ushort deltaA = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
591-
a += deltaA;
592-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, a);
593-
offset += 2;
594-
}
619+
UndoRgb64BitLittleEndianRow(pixelBytes, width, y);
595620
}
596621
}
597622
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ public void TiffDecoder_CanDecode_Planar<TPixel>(TestImageProvider<TPixel> provi
9696
[WithFile(TiledGray32BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9797
[WithFile(TiledRgb48BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9898
[WithFile(TiledRgb48BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
99+
[WithFile(TiledRgba64BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
100+
[WithFile(TiledRgba64BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
99101
public void TiffDecoder_CanDecode_Tiled<TPixel>(TestImageProvider<TPixel> provider)
100102
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
101103

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,8 @@ public static class Tiff
995995
public const string TiledGray32BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_32bit_big_endian_deflate_compressed_predictor.tiff";
996996
public const string TiledRgb48BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_little_endian_deflate_compressed_predictor.tiff";
997997
public const string TiledRgb48BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_big_endian_deflate_compressed_predictor.tiff";
998+
public const string TiledRgba64BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_64bit_little_endian_deflate_compressed_predictor.tiff";
999+
public const string TiledRgba64BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_64bit_big_endian_deflate_compressed_predictor.tiff";
9981000

9991001
// Images with alpha channel.
10001002
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:f456272c6948159ea17d6fa7d2a89e30521c1d4e29f0ad0b1a79894f122d2153
3+
size 220119
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:ee63d8b0d63fd091390678a4a2600df5c14a122002a4d9c93e7d01082a2ee347
3+
size 220045

0 commit comments

Comments
 (0)