@@ -41,7 +41,7 @@ internal class HuffmanScanEncoder
4141 private int emitLen = 0 ;
4242
4343 /// <summary>
44- /// Emmited bits 'micro buffer' before being transfered to the <see cref="emitBuffer"/>.
44+ /// Emitted bits 'micro buffer' before being transferred to the <see cref="emitBuffer"/>.
4545 /// </summary>
4646 private int accumulatedBits ;
4747
@@ -58,18 +58,15 @@ internal class HuffmanScanEncoder
5858 /// </summary>
5959 private readonly Stream target ;
6060
61- public HuffmanScanEncoder ( Stream outputStream )
62- {
63- this . target = outputStream ;
64- }
61+ public HuffmanScanEncoder ( Stream outputStream ) => this . target = outputStream ;
6562
6663 /// <summary>
6764 /// Encodes the image with no subsampling.
6865 /// </summary>
6966 /// <typeparam name="TPixel">The pixel format.</typeparam>
7067 /// <param name="pixels">The pixel accessor providing access to the image pixels.</param>
71- /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee</param>
72- /// <param name="chrominanceQuantTable">Chrominance quantization table provided by the callee</param>
68+ /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee. </param>
69+ /// <param name="chrominanceQuantTable">Chrominance quantization table provided by the callee. </param>
7370 /// <param name="cancellationToken">The token to monitor for cancellation.</param>
7471 public void Encode444 < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , ref Block8x8F chrominanceQuantTable , CancellationToken cancellationToken )
7572 where TPixel : unmanaged, IPixel < TPixel >
@@ -128,8 +125,8 @@ public void Encode444<TPixel>(Image<TPixel> pixels, ref Block8x8F luminanceQuant
128125 /// </summary>
129126 /// <typeparam name="TPixel">The pixel format.</typeparam>
130127 /// <param name="pixels">The pixel accessor providing access to the image pixels.</param>
131- /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee</param>
132- /// <param name="chrominanceQuantTable">Chrominance quantization table provided by the callee</param>
128+ /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee. </param>
129+ /// <param name="chrominanceQuantTable">Chrominance quantization table provided by the callee. </param>
133130 /// <param name="cancellationToken">The token to monitor for cancellation.</param>
134131 public void Encode420 < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , ref Block8x8F chrominanceQuantTable , CancellationToken cancellationToken )
135132 where TPixel : unmanaged, IPixel < TPixel >
@@ -196,7 +193,7 @@ public void Encode420<TPixel>(Image<TPixel> pixels, ref Block8x8F luminanceQuant
196193 /// </summary>
197194 /// <typeparam name="TPixel">The pixel format.</typeparam>
198195 /// <param name="pixels">The pixel accessor providing access to the image pixels.</param>
199- /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee</param>
196+ /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee. </param>
200197 /// <param name="cancellationToken">The token to monitor for cancellation.</param>
201198 public void EncodeGrayscale < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , CancellationToken cancellationToken )
202199 where TPixel : unmanaged, IPixel < TPixel >
@@ -234,6 +231,64 @@ public void EncodeGrayscale<TPixel>(Image<TPixel> pixels, ref Block8x8F luminanc
234231 this . FlushInternalBuffer ( ) ;
235232 }
236233
234+ /// <summary>
235+ /// Encodes the image with no subsampling and keeps the pixel data as Rgb24.
236+ /// </summary>
237+ /// <typeparam name="TPixel">The pixel format.</typeparam>
238+ /// <param name="pixels">The pixel accessor providing access to the image pixels.</param>
239+ /// <param name="luminanceQuantTable">Luminance quantization table provided by the callee.</param>
240+ /// <param name="cancellationToken">The token to monitor for cancellation.</param>
241+ public void EncodeRgb < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , CancellationToken cancellationToken )
242+ where TPixel : unmanaged, IPixel < TPixel >
243+ {
244+ this . huffmanTables = HuffmanLut . TheHuffmanLut ;
245+
246+ var unzig = ZigZag . CreateUnzigTable ( ) ;
247+
248+ // ReSharper disable once InconsistentNaming
249+ int prevDCR = 0 , prevDCG = 0 , prevDCB = 0 ;
250+
251+ ImageFrame < TPixel > frame = pixels . Frames . RootFrame ;
252+ Buffer2D < TPixel > pixelBuffer = frame . PixelBuffer ;
253+ RowOctet < TPixel > currentRows = default ;
254+
255+ var pixelConverter = new RgbForwardConverter < TPixel > ( frame ) ;
256+
257+ for ( int y = 0 ; y < pixels . Height ; y += 8 )
258+ {
259+ cancellationToken . ThrowIfCancellationRequested ( ) ;
260+ currentRows . Update ( pixelBuffer , y ) ;
261+
262+ for ( int x = 0 ; x < pixels . Width ; x += 8 )
263+ {
264+ pixelConverter . Convert ( x , y , ref currentRows ) ;
265+
266+ prevDCR = this . WriteBlock (
267+ QuantIndex . Luminance ,
268+ prevDCR ,
269+ ref pixelConverter . R ,
270+ ref luminanceQuantTable ,
271+ ref unzig ) ;
272+
273+ prevDCG = this . WriteBlock (
274+ QuantIndex . Luminance ,
275+ prevDCG ,
276+ ref pixelConverter . G ,
277+ ref luminanceQuantTable ,
278+ ref unzig ) ;
279+
280+ prevDCB = this . WriteBlock (
281+ QuantIndex . Luminance ,
282+ prevDCB ,
283+ ref pixelConverter . B ,
284+ ref luminanceQuantTable ,
285+ ref unzig ) ;
286+ }
287+ }
288+
289+ this . FlushInternalBuffer ( ) ;
290+ }
291+
237292 /// <summary>
238293 /// Writes a block of pixel data using the given quantization table,
239294 /// returning the post-quantized DC value of the DCT-transformed block.
@@ -437,7 +492,7 @@ internal static int GetHuffmanEncodingLength(uint value)
437492 DebugGuard . IsTrue ( value <= ( 1 << 16 ) , "Huffman encoder is supposed to encode a value of 16bit size max" ) ;
438493#if SUPPORTS_BITOPERATIONS
439494 // This should have been implemented as (BitOperations.Log2(value) + 1) as in non-intrinsic implementation
440- // But internal log2 is implementated like this: (31 - (int)Lzcnt.LeadingZeroCount(value))
495+ // But internal log2 is implemented like this: (31 - (int)Lzcnt.LeadingZeroCount(value))
441496
442497 // BitOperations.Log2 implementation also checks if input value is zero for the convention 0->0
443498 // Lzcnt would return 32 for input value of 0 - no need to check that with branching
@@ -449,7 +504,7 @@ internal static int GetHuffmanEncodingLength(uint value)
449504 // if 0 - return 0 in this case
450505 // else - return log2(value) + 1
451506 //
452- // Hack based on input value constaint :
507+ // Hack based on input value constraint :
453508 // We know that input values are guaranteed to be maximum 16 bit large for huffman encoding
454509 // We can safely shift input value for one bit -> log2(value << 1)
455510 // Because of the 16 bit value constraint it won't overflow
0 commit comments