From e83cb95cb377df22d51ec0f95cb4ebf1ce122d27 Mon Sep 17 00:00:00 2001 From: Dmitry Pentin Date: Tue, 17 Aug 2021 12:24:37 +0300 Subject: [PATCH] Moved stuff bytes injection to outer method --- .../Components/Encoder/HuffmanScanEncoder.cs | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs index 331da275c..778d6ccd8 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs @@ -35,6 +35,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder /// private readonly byte[] emitBuffer = new byte[EmitBufferSizeInBytes]; + private readonly byte[] streamWriteBuffer = new byte[EmitBufferSizeInBytes * 2]; + + private const int BytesPerCodingUnit = 256 * 3; + /// /// Number of filled bytes in buffer /// @@ -116,6 +120,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder ref pixelConverter.Cr, ref chrominanceQuantTable, ref unzig); + + if (this.emitLen + BytesPerCodingUnit > EmitBufferSizeInBytes) + { + this.WriteToStream(); + } } } @@ -326,28 +335,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder byte b = (byte)(bits >> 24); this.emitBuffer[this.emitLen++] = b; - // Adding stuff byte - // This is because by JPEG standard scan data can contain JPEG markers (indicated by the 0xFF byte, followed by a non-zero byte) - // Considering this every 0xFF byte must be followed by 0x00 padding byte to signal that this is not a marker - if (b == byte.MaxValue) - { - this.emitBuffer[this.emitLen++] = byte.MinValue; - } - bits <<= 8; count -= 8; } - - // This can emit 4 times of: - // 1 byte guaranteed - // 1 extra byte.MinValue byte if previous one was byte.MaxValue - // Thus writing (1 + 1) * 4 = 8 bytes max - // So we must check if emit buffer has extra 8 bytes, if not - call stream.Write - if (this.emitLen > EmitBufferSizeInBytes - 8) - { - this.target.Write(this.emitBuffer, 0, this.emitLen); - this.emitLen = 0; - } } this.accumulatedBits = bits; @@ -520,5 +510,23 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder return index; } } + + [MethodImpl(InliningOptions.ShortMethod)] + private void WriteToStream() + { + int writeIdx = 0; + for (int i = 0; i < this.emitLen; i++) + { + byte value = this.emitBuffer[i]; + this.streamWriteBuffer[writeIdx++] = value; + if (value == 0xff) + { + this.streamWriteBuffer[writeIdx++] = 0x00; + } + } + + this.target.Write(this.streamWriteBuffer, 0, writeIdx); + this.emitLen = 0; + } } }