Skip to content

Commit f11fbc1

Browse files
committed
Add test cases for tiled 16 bit gray tiff's
1 parent e3c7471 commit f11fbc1

File tree

6 files changed

+64
-28
lines changed

6 files changed

+64
-28
lines changed

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

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static void Undo(Span<byte> pixelBytes, int width, TiffColorType colorTyp
6262
}
6363
}
6464

65-
public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorType colorType)
65+
public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorType colorType, bool isBigEndian)
6666
{
6767
// TODO: Implement missing colortypes, see above.
6868
switch (colorType)
@@ -71,6 +71,18 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
7171
case TiffColorType.WhiteIsZero8:
7272
case TiffColorType.PaletteColor:
7373
UndoGray8BitRow(pixelBytes, width, y);
74+
break;
75+
case TiffColorType.BlackIsZero16:
76+
case TiffColorType.WhiteIsZero16:
77+
if (isBigEndian)
78+
{
79+
UndoGray16BitBigEndianRow(pixelBytes, width, y);
80+
}
81+
else
82+
{
83+
UndoGray16BitLittleEndianRow(pixelBytes, width, y);
84+
}
85+
7486
break;
7587
case TiffColorType.Rgb888:
7688
case TiffColorType.CieLab:
@@ -196,6 +208,44 @@ private static void UndoGray8Bit(Span<byte> pixelBytes, int width)
196208
}
197209
}
198210

211+
private static void UndoGray16BitBigEndianRow(Span<byte> pixelBytes, int width, int y)
212+
{
213+
int rowBytesCount = width * 2;
214+
int height = pixelBytes.Length / rowBytesCount;
215+
int offset = 0;
216+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
217+
ushort pixelValue = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
218+
offset += 2;
219+
220+
for (int x = 1; x < width; x++)
221+
{
222+
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
223+
ushort diff = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
224+
pixelValue += diff;
225+
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, pixelValue);
226+
offset += 2;
227+
}
228+
}
229+
230+
private static void UndoGray16BitLittleEndianRow(Span<byte> pixelBytes, int width, int y)
231+
{
232+
int rowBytesCount = width * 2;
233+
int height = pixelBytes.Length / rowBytesCount;
234+
int offset = 0;
235+
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
236+
ushort pixelValue = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
237+
offset += 2;
238+
239+
for (int x = 1; x < width; x++)
240+
{
241+
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
242+
ushort diff = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
243+
pixelValue += diff;
244+
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, pixelValue);
245+
offset += 2;
246+
}
247+
}
248+
199249
private static void UndoGray16Bit(Span<byte> pixelBytes, int width, bool isBigEndian)
200250
{
201251
int rowBytesCount = width * 2;
@@ -204,38 +254,14 @@ private static void UndoGray16Bit(Span<byte> pixelBytes, int width, bool isBigEn
204254
{
205255
for (int y = 0; y < height; y++)
206256
{
207-
int offset = 0;
208-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
209-
ushort pixelValue = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
210-
offset += 2;
211-
212-
for (int x = 1; x < width; x++)
213-
{
214-
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
215-
ushort diff = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
216-
pixelValue += diff;
217-
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, pixelValue);
218-
offset += 2;
219-
}
257+
UndoGray16BitBigEndianRow(pixelBytes, width, y);
220258
}
221259
}
222260
else
223261
{
224262
for (int y = 0; y < height; y++)
225263
{
226-
int offset = 0;
227-
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
228-
ushort pixelValue = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
229-
offset += 2;
230-
231-
for (int x = 1; x < width; x++)
232-
{
233-
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
234-
ushort diff = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
235-
pixelValue += diff;
236-
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, pixelValue);
237-
offset += 2;
238-
}
264+
UndoGray16BitLittleEndianRow(pixelBytes, width, y);
239265
}
240266
}
241267
}

src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ private void DecodeTilesChunky<TPixel>(
718718
if (this.Predictor == TiffPredictor.Horizontal)
719719
{
720720
int pixelsInTileRow = isLastHorizontalTile ? remainingPixelsInRow : tileLength;
721-
HorizontalPredictor.UndoRow(uncompressedPixelRow, pixelsInTileRow, 0, this.ColorType);
721+
HorizontalPredictor.UndoRow(uncompressedPixelRow, pixelsInTileRow, 0, this.ColorType, this.byteOrder == ByteOrder.BigEndian);
722722
}
723723

724724
tileBufferOffset += bytesPerTileRow;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ public void TiffDecoder_CanDecode_Planar<TPixel>(TestImageProvider<TPixel> provi
9090
[WithFile(TiledRgbaDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9191
[WithFile(TiledRgbDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9292
[WithFile(TiledGrayDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
93+
[WithFile(TiledGray16BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
94+
[WithFile(TiledGray16BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
9395
public void TiffDecoder_CanDecode_Tiled<TPixel>(TestImageProvider<TPixel> provider)
9496
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
9597

tests/ImageSharp.Tests/TestImages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,8 @@ public static class Tiff
989989
public const string TiledRgbaDeflateCompressedWithPredictor = "Tiff/tiled_rgba_deflate_compressed_predictor.tiff";
990990
public const string TiledRgbDeflateCompressedWithPredictor = "Tiff/tiled_rgb_deflate_compressed_predictor.tiff";
991991
public const string TiledGrayDeflateCompressedWithPredictor = "Tiff/tiled_gray_deflate_compressed_predictor.tiff";
992+
public const string TiledGray16BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_little_endian_deflate_compressed_predictor.tiff";
993+
public const string TiledGray16BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff";
992994

993995
// Images with alpha channel.
994996
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:e267cf78bebba51628f0aca98c8720e8ea8013b9e5f96c8f12df1c153f34f065
3+
size 80195
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:19b4a2ee8761e0016a598f66f12eb62edf4c4d30f33694d30986ce84516ac454
3+
size 80177

0 commit comments

Comments
 (0)