@@ -41,7 +41,7 @@ internal class HuffmanScanEncoder
41
41
private int emitLen = 0 ;
42
42
43
43
/// <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"/>.
45
45
/// </summary>
46
46
private int accumulatedBits ;
47
47
@@ -58,18 +58,15 @@ internal class HuffmanScanEncoder
58
58
/// </summary>
59
59
private readonly Stream target ;
60
60
61
- public HuffmanScanEncoder ( Stream outputStream )
62
- {
63
- this . target = outputStream ;
64
- }
61
+ public HuffmanScanEncoder ( Stream outputStream ) => this . target = outputStream ;
65
62
66
63
/// <summary>
67
64
/// Encodes the image with no subsampling.
68
65
/// </summary>
69
66
/// <typeparam name="TPixel">The pixel format.</typeparam>
70
67
/// <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>
73
70
/// <param name="cancellationToken">The token to monitor for cancellation.</param>
74
71
public void Encode444 < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , ref Block8x8F chrominanceQuantTable , CancellationToken cancellationToken )
75
72
where TPixel : unmanaged, IPixel < TPixel >
@@ -128,8 +125,8 @@ public void Encode444<TPixel>(Image<TPixel> pixels, ref Block8x8F luminanceQuant
128
125
/// </summary>
129
126
/// <typeparam name="TPixel">The pixel format.</typeparam>
130
127
/// <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>
133
130
/// <param name="cancellationToken">The token to monitor for cancellation.</param>
134
131
public void Encode420 < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , ref Block8x8F chrominanceQuantTable , CancellationToken cancellationToken )
135
132
where TPixel : unmanaged, IPixel < TPixel >
@@ -196,7 +193,7 @@ public void Encode420<TPixel>(Image<TPixel> pixels, ref Block8x8F luminanceQuant
196
193
/// </summary>
197
194
/// <typeparam name="TPixel">The pixel format.</typeparam>
198
195
/// <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>
200
197
/// <param name="cancellationToken">The token to monitor for cancellation.</param>
201
198
public void EncodeGrayscale < TPixel > ( Image < TPixel > pixels , ref Block8x8F luminanceQuantTable , CancellationToken cancellationToken )
202
199
where TPixel : unmanaged, IPixel < TPixel >
@@ -234,6 +231,64 @@ public void EncodeGrayscale<TPixel>(Image<TPixel> pixels, ref Block8x8F luminanc
234
231
this . FlushInternalBuffer ( ) ;
235
232
}
236
233
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
+
237
292
/// <summary>
238
293
/// Writes a block of pixel data using the given quantization table,
239
294
/// returning the post-quantized DC value of the DCT-transformed block.
@@ -437,7 +492,7 @@ internal static int GetHuffmanEncodingLength(uint value)
437
492
DebugGuard . IsTrue ( value <= ( 1 << 16 ) , "Huffman encoder is supposed to encode a value of 16bit size max" ) ;
438
493
#if SUPPORTS_BITOPERATIONS
439
494
// 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))
441
496
442
497
// BitOperations.Log2 implementation also checks if input value is zero for the convention 0->0
443
498
// 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)
449
504
// if 0 - return 0 in this case
450
505
// else - return log2(value) + 1
451
506
//
452
- // Hack based on input value constaint :
507
+ // Hack based on input value constraint :
453
508
// We know that input values are guaranteed to be maximum 16 bit large for huffman encoding
454
509
// We can safely shift input value for one bit -> log2(value << 1)
455
510
// Because of the 16 bit value constraint it won't overflow
0 commit comments