Browse Source

Add method UndoTile in HorizontalPredictor

pull/2878/head
Brian Popow 12 months ago
parent
commit
71f7d86900
  1. 17
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs
  2. 8
      src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs
  3. 6
      src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
  4. 8
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  5. 2
      tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs

17
src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs

@ -24,6 +24,8 @@ internal sealed class DeflateTiffCompression : TiffBaseDecompressor
private readonly bool isTiled;
private readonly int tileWidth;
/// <summary>
/// Initializes a new instance of the <see cref="DeflateTiffCompression" /> class.
/// </summary>
@ -34,12 +36,14 @@ internal sealed class DeflateTiffCompression : TiffBaseDecompressor
/// <param name="predictor">The tiff predictor used.</param>
/// <param name="isBigEndian">if set to <c>true</c> decodes the pixel data as big endian, otherwise as little endian.</param>
/// <param name="isTiled">Flag indicates, if the image is a tiled image.</param>
public DeflateTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, bool isBigEndian, bool isTiled)
/// <param name="tileWidth">Number of pixels in a tile row.</param>
public DeflateTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, bool isBigEndian, bool isTiled, int tileWidth)
: base(memoryAllocator, width, bitsPerPixel, predictor)
{
this.colorType = colorType;
this.isBigEndian = isBigEndian;
this.isTiled = isTiled;
this.tileWidth = tileWidth;
}
/// <inheritdoc/>
@ -73,9 +77,16 @@ internal sealed class DeflateTiffCompression : TiffBaseDecompressor
}
// When the image is tiled, undoing the horizontal predictor will be done for each tile row in the DecodeTilesChunky() method.
if (this.Predictor == TiffPredictor.Horizontal && !this.isTiled)
if (this.Predictor == TiffPredictor.Horizontal)
{
HorizontalPredictor.Undo(buffer, this.Width, this.colorType, this.isBigEndian);
if (this.isTiled)
{
HorizontalPredictor.UndoTile(buffer, this.tileWidth, this.colorType, this.isBigEndian);
}
else
{
HorizontalPredictor.Undo(buffer, this.Width, this.colorType, this.isBigEndian);
}
}
}

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

@ -62,6 +62,14 @@ internal static class HorizontalPredictor
}
}
public static void UndoTile(Span<byte> pixelBytes, int tileWidth, TiffColorType colorType, bool isBigEndian)
{
for (int y = 0; y < tileWidth; y++)
{
UndoRow(pixelBytes, tileWidth, y, colorType, isBigEndian);
}
}
/// <summary>
/// Inverts the horizontal predictor for one row.
/// </summary>

6
src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Tiff.Compression;
@ -25,7 +24,8 @@ internal static class TiffDecompressorsFactory
uint oldJpegStartOfImageMarker,
TiffFillOrder fillOrder,
ByteOrder byteOrder,
bool isTiled = false)
bool isTiled = false,
int tileWidth = 0)
{
switch (method)
{
@ -41,7 +41,7 @@ internal static class TiffDecompressorsFactory
case TiffDecoderCompressionType.Deflate:
DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected");
return new DeflateTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian, isTiled);
return new DeflateTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian, isTiled, tileWidth);
case TiffDecoderCompressionType.Lzw:
DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected");

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

@ -679,8 +679,7 @@ internal class TiffDecoderCore : ImageDecoderCore
using IMemoryOwner<byte> tileBuffer = this.memoryAllocator.Allocate<byte>(bytesPerTileRow * tileLength, AllocationOptions.Clean);
Span<byte> tileBufferSpan = tileBuffer.GetSpan();
bool isTiled = true;
using TiffBaseDecompressor decompressor = this.CreateDecompressor<TPixel>(frame.Width, bitsPerPixel, isTiled);
using TiffBaseDecompressor decompressor = this.CreateDecompressor<TPixel>(frame.Width, bitsPerPixel, true, tileWidth);
TiffBaseColorDecoder<TPixel> colorDecoder = this.CreateChunkyColorDecoder<TPixel>();
int tileIndex = 0;
@ -748,7 +747,7 @@ internal class TiffDecoderCore : ImageDecoderCore
this.YcbcrSubSampling,
this.byteOrder);
private TiffBaseDecompressor CreateDecompressor<TPixel>(int frameWidth, int bitsPerPixel, bool isTiled = false)
private TiffBaseDecompressor CreateDecompressor<TPixel>(int frameWidth, int bitsPerPixel, bool isTiled = false, int tileWidth = 0)
where TPixel : unmanaged, IPixel<TPixel> =>
TiffDecompressorsFactory.Create(
this.Options,
@ -764,7 +763,8 @@ internal class TiffDecoderCore : ImageDecoderCore
this.OldJpegCompressionStartOfImageMarker.GetValueOrDefault(),
this.FillOrder,
this.byteOrder,
isTiled);
isTiled,
tileWidth);
private IMemoryOwner<ulong> ConvertNumbers(Array array, out Span<ulong> span)
{

2
tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs

@ -23,7 +23,7 @@ public class DeflateTiffCompressionTests
using BufferedReadStream stream = CreateCompressedStream(data);
byte[] buffer = new byte[data.Length];
using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false, false);
using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false, false, 0);
decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer, default);

Loading…
Cancel
Save