Skip to content

Commit 97133fe

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

File tree

5 files changed

+95
-58
lines changed

5 files changed

+95
-58
lines changed

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

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
103103
case TiffColorType.Rgba8888:
104104
case TiffColorType.Cmyk:
105105
UndoRgba32BitRow(pixelBytes, width, y);
106+
break;
107+
case TiffColorType.Rgb161616:
108+
if (isBigEndian)
109+
{
110+
UndoRgb48BitBigEndianRow(pixelBytes, width, y);
111+
}
112+
else
113+
{
114+
UndoRgb48BitLittleEndianRow(pixelBytes, width, y);
115+
}
116+
106117
break;
107118
}
108119
}
@@ -401,6 +412,78 @@ private static void UndoRgba32Bit(Span<byte> pixelBytes, int width)
401412
}
402413
}
403414

415+
private static void UndoRgb48BitBigEndianRow(Span<byte> pixelBytes, int width, int y)
416+
{
417+
int rowBytesCount = width * 6;
418+
int height = pixelBytes.Length / rowBytesCount;
419+
420+
int offset = 0;
421+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
422+
ushort r = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
423+
offset += 2;
424+
ushort g = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
425+
offset += 2;
426+
ushort b = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
427+
offset += 2;
428+
429+
for (int x = 1; x < width; x++)
430+
{
431+
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
432+
ushort deltaR = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
433+
r += deltaR;
434+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, r);
435+
offset += 2;
436+
437+
rowSpan = rowBytes.Slice(offset, 2);
438+
ushort deltaG = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
439+
g += deltaG;
440+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, g);
441+
offset += 2;
442+
443+
rowSpan = rowBytes.Slice(offset, 2);
444+
ushort deltaB = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
445+
b += deltaB;
446+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, b);
447+
offset += 2;
448+
}
449+
}
450+
451+
private static void UndoRgb48BitLittleEndianRow(Span<byte> pixelBytes, int width, int y)
452+
{
453+
int rowBytesCount = width * 6;
454+
int height = pixelBytes.Length / rowBytesCount;
455+
456+
int offset = 0;
457+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
458+
ushort r = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
459+
offset += 2;
460+
ushort g = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
461+
offset += 2;
462+
ushort b = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
463+
offset += 2;
464+
465+
for (int x = 1; x < width; x++)
466+
{
467+
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
468+
ushort deltaR = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
469+
r += deltaR;
470+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, r);
471+
offset += 2;
472+
473+
rowSpan = rowBytes.Slice(offset, 2);
474+
ushort deltaG = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
475+
g += deltaG;
476+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, g);
477+
offset += 2;
478+
479+
rowSpan = rowBytes.Slice(offset, 2);
480+
ushort deltaB = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
481+
b += deltaB;
482+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, b);
483+
offset += 2;
484+
}
485+
}
486+
404487
private static void UndoRgb48Bit(Span<byte> pixelBytes, int width, bool isBigEndian)
405488
{
406489
int rowBytesCount = width * 6;
@@ -409,70 +492,14 @@ private static void UndoRgb48Bit(Span<byte> pixelBytes, int width, bool isBigEnd
409492
{
410493
for (int y = 0; y < height; y++)
411494
{
412-
int offset = 0;
413-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
414-
ushort r = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
415-
offset += 2;
416-
ushort g = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
417-
offset += 2;
418-
ushort b = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
419-
offset += 2;
420-
421-
for (int x = 1; x < width; x++)
422-
{
423-
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
424-
ushort deltaR = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
425-
r += deltaR;
426-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, r);
427-
offset += 2;
428-
429-
rowSpan = rowBytes.Slice(offset, 2);
430-
ushort deltaG = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
431-
g += deltaG;
432-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, g);
433-
offset += 2;
434-
435-
rowSpan = rowBytes.Slice(offset, 2);
436-
ushort deltaB = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
437-
b += deltaB;
438-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, b);
439-
offset += 2;
440-
}
495+
UndoRgb48BitBigEndianRow(pixelBytes, width, y);
441496
}
442497
}
443498
else
444499
{
445500
for (int y = 0; y < height; y++)
446501
{
447-
int offset = 0;
448-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
449-
ushort r = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
450-
offset += 2;
451-
ushort g = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
452-
offset += 2;
453-
ushort b = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
454-
offset += 2;
455-
456-
for (int x = 1; x < width; x++)
457-
{
458-
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
459-
ushort deltaR = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
460-
r += deltaR;
461-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, r);
462-
offset += 2;
463-
464-
rowSpan = rowBytes.Slice(offset, 2);
465-
ushort deltaG = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
466-
g += deltaG;
467-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, g);
468-
offset += 2;
469-
470-
rowSpan = rowBytes.Slice(offset, 2);
471-
ushort deltaB = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
472-
b += deltaB;
473-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, b);
474-
offset += 2;
475-
}
502+
UndoRgb48BitLittleEndianRow(pixelBytes, width, y);
476503
}
477504
}
478505
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ public void TiffDecoder_CanDecode_Planar<TPixel>(TestImageProvider<TPixel> provi
9494
[WithFile(TiledGray16BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9595
[WithFile(TiledGray32BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9696
[WithFile(TiledGray32BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
97+
[WithFile(TiledRgb48BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
98+
[WithFile(TiledRgb48BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9799
public void TiffDecoder_CanDecode_Tiled<TPixel>(TestImageProvider<TPixel> provider)
98100
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
99101

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,8 @@ public static class Tiff
993993
public const string TiledGray16BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff";
994994
public const string TiledGray32BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_32bit_little_endian_deflate_compressed_predictor.tiff";
995995
public const string TiledGray32BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_32bit_big_endian_deflate_compressed_predictor.tiff";
996+
public const string TiledRgb48BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_little_endian_deflate_compressed_predictor.tiff";
997+
public const string TiledRgb48BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_big_endian_deflate_compressed_predictor.tiff";
996998

997999
// Images with alpha channel.
9981000
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:0880733f8463aff1feefcc08ce21860d7fb1c8c32e19aa96143bf5679a353fba
3+
size 201673
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:0880733f8463aff1feefcc08ce21860d7fb1c8c32e19aa96143bf5679a353fba
3+
size 201673

0 commit comments

Comments
 (0)