Browse Source

Add test cases for tiled 16 bit gray tiff's

pull/2878/head
Brian Popow 1 year ago
parent
commit
f11fbc14d9
  1. 80
      src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs
  2. 2
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  3. 2
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  4. 2
      tests/ImageSharp.Tests/TestImages.cs
  5. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff
  6. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_little_endian_deflate_compressed_predictor.tiff

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

@ -62,7 +62,7 @@ internal static class HorizontalPredictor
}
}
public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorType colorType)
public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorType colorType, bool isBigEndian)
{
// TODO: Implement missing colortypes, see above.
switch (colorType)
@ -71,6 +71,18 @@ internal static class HorizontalPredictor
case TiffColorType.WhiteIsZero8:
case TiffColorType.PaletteColor:
UndoGray8BitRow(pixelBytes, width, y);
break;
case TiffColorType.BlackIsZero16:
case TiffColorType.WhiteIsZero16:
if (isBigEndian)
{
UndoGray16BitBigEndianRow(pixelBytes, width, y);
}
else
{
UndoGray16BitLittleEndianRow(pixelBytes, width, y);
}
break;
case TiffColorType.Rgb888:
case TiffColorType.CieLab:
@ -196,6 +208,44 @@ internal static class HorizontalPredictor
}
}
private static void UndoGray16BitBigEndianRow(Span<byte> pixelBytes, int width, int y)
{
int rowBytesCount = width * 2;
int height = pixelBytes.Length / rowBytesCount;
int offset = 0;
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
ushort pixelValue = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
offset += 2;
for (int x = 1; x < width; x++)
{
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
ushort diff = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
pixelValue += diff;
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, pixelValue);
offset += 2;
}
}
private static void UndoGray16BitLittleEndianRow(Span<byte> pixelBytes, int width, int y)
{
int rowBytesCount = width * 2;
int height = pixelBytes.Length / rowBytesCount;
int offset = 0;
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
ushort pixelValue = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
offset += 2;
for (int x = 1; x < width; x++)
{
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
ushort diff = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
pixelValue += diff;
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, pixelValue);
offset += 2;
}
}
private static void UndoGray16Bit(Span<byte> pixelBytes, int width, bool isBigEndian)
{
int rowBytesCount = width * 2;
@ -204,38 +254,14 @@ internal static class HorizontalPredictor
{
for (int y = 0; y < height; y++)
{
int offset = 0;
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
ushort pixelValue = TiffUtilities.ConvertToUShortBigEndian(rowBytes.Slice(offset, 2));
offset += 2;
for (int x = 1; x < width; x++)
{
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
ushort diff = TiffUtilities.ConvertToUShortBigEndian(rowSpan);
pixelValue += diff;
BinaryPrimitives.WriteUInt16BigEndian(rowSpan, pixelValue);
offset += 2;
}
UndoGray16BitBigEndianRow(pixelBytes, width, y);
}
}
else
{
for (int y = 0; y < height; y++)
{
int offset = 0;
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
ushort pixelValue = TiffUtilities.ConvertToUShortLittleEndian(rowBytes.Slice(offset, 2));
offset += 2;
for (int x = 1; x < width; x++)
{
Span<byte> rowSpan = rowBytes.Slice(offset, 2);
ushort diff = TiffUtilities.ConvertToUShortLittleEndian(rowSpan);
pixelValue += diff;
BinaryPrimitives.WriteUInt16LittleEndian(rowSpan, pixelValue);
offset += 2;
}
UndoGray16BitLittleEndianRow(pixelBytes, width, y);
}
}
}

2
src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

@ -718,7 +718,7 @@ internal class TiffDecoderCore : ImageDecoderCore
if (this.Predictor == TiffPredictor.Horizontal)
{
int pixelsInTileRow = isLastHorizontalTile ? remainingPixelsInRow : tileLength;
HorizontalPredictor.UndoRow(uncompressedPixelRow, pixelsInTileRow, 0, this.ColorType);
HorizontalPredictor.UndoRow(uncompressedPixelRow, pixelsInTileRow, 0, this.ColorType, this.byteOrder == ByteOrder.BigEndian);
}
tileBufferOffset += bytesPerTileRow;

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

@ -90,6 +90,8 @@ public class TiffDecoderTests : TiffDecoderBaseTester
[WithFile(TiledRgbaDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgbDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGrayDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray16BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray16BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
public void TiffDecoder_CanDecode_Tiled<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);

2
tests/ImageSharp.Tests/TestImages.cs

@ -989,6 +989,8 @@ public static class TestImages
public const string TiledRgbaDeflateCompressedWithPredictor = "Tiff/tiled_rgba_deflate_compressed_predictor.tiff";
public const string TiledRgbDeflateCompressedWithPredictor = "Tiff/tiled_rgb_deflate_compressed_predictor.tiff";
public const string TiledGrayDeflateCompressedWithPredictor = "Tiff/tiled_gray_deflate_compressed_predictor.tiff";
public const string TiledGray16BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_little_endian_deflate_compressed_predictor.tiff";
public const string TiledGray16BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff";
// Images with alpha channel.
public const string Rgba2BitUnassociatedAlpha = "Tiff/RgbaUnassociatedAlpha2bit.tiff";

3
tests/Images/Input/Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e267cf78bebba51628f0aca98c8720e8ea8013b9e5f96c8f12df1c153f34f065
size 80195

3
tests/Images/Input/Tiff/tiled_gray_16bit_little_endian_deflate_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:19b4a2ee8761e0016a598f66f12eb62edf4c4d30f33694d30986ce84516ac454
size 80177
Loading…
Cancel
Save