From a26bfe01236444c9b2129bb53d2df3f03a0b1a45 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 30 May 2022 09:01:28 +0200 Subject: [PATCH] Access data span only for new byte, not for every bit --- .../Decompressors/ModifiedHuffmanBitReader.cs | 3 +- .../Compression/Decompressors/T4BitReader.cs | 36 ++++++++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanBitReader.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanBitReader.cs index 89cdf7ea2..4a87e2951 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanBitReader.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanBitReader.cs @@ -57,8 +57,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors if (remainder != 0) { // Skip padding bits, move to next byte. - this.Position++; - this.ResetBitsRead(); + this.AdvancePosition(); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs index 15e2b3c30..1053ca107 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs @@ -229,12 +229,20 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors this.RunLength = 0; this.eolPadding = eolPadding; + Span dataSpan = this.Data.GetSpan(); + this.DataAtPosition = dataSpan[(int)this.Position]; + if (this.eolPadding) { this.maxCodeLength = 24; } } + /// + /// Gets or sets the byte at the given position. + /// + private byte DataAtPosition { get; set; } + /// /// Gets the current value. /// @@ -453,6 +461,23 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors return v; } + /// + /// Advances the position by one byte. + /// + /// True, if data could be advanced by one byte. + protected bool AdvancePosition() + { + this.LoadNewByte(); + if (this.Position < (ulong)this.DataLength) + { + Span dataSpan = this.Data.GetSpan(); + this.DataAtPosition = Unsafe.Add(ref MemoryMarshal.GetReference(dataSpan), (int)this.Position); + return true; + } + + return false; + } + private uint WhiteTerminatingCodeRunLength() { switch (this.CurValueBitsRead) @@ -811,13 +836,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors { if (this.BitsRead >= 8) { - this.LoadNewByte(); + this.AdvancePosition(); } - Span dataSpan = this.Data.GetSpan(); int shift = 8 - this.BitsRead - 1; - ref byte dataAtPosition = ref Unsafe.Add(ref MemoryMarshal.GetReference(dataSpan), (int)this.Position); - uint bit = (uint)((dataAtPosition & (1 << shift)) != 0 ? 1 : 0); + uint bit = (uint)((this.DataAtPosition & (1 << shift)) != 0 ? 1 : 0); this.BitsRead++; return bit; @@ -827,11 +850,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors { this.Position++; this.ResetBitsRead(); - - if (this.Position >= (ulong)this.DataLength) - { - TiffThrowHelper.ThrowImageFormatException("tiff image has invalid ccitt compressed data"); - } } private void ReadImageDataFromStream(Stream input, int bytesToRead)