@@ -241,14 +241,18 @@ ref Unsafe.Add(ref blockRef, k),
241241 /// Encodes the DC coefficients for a given component's blocks in a scan.
242242 /// </summary>
243243 /// <param name="component">The component whose DC coefficients need to be encoded.</param>
244+ /// <param name="restartInterval">Numbers of MCUs between restart markers.</param>
244245 /// <param name="cancellationToken">The token to request cancellation.</param>
245- public void EncodeDcScan ( Component component , CancellationToken cancellationToken )
246+ public void EncodeDcScan ( Component component , int restartInterval , CancellationToken cancellationToken )
246247 {
247248 int h = component . HeightInBlocks ;
248249 int w = component . WidthInBlocks ;
249250
250251 ref HuffmanLut dcHuffmanTable = ref this . dcHuffmanTables [ component . DcTableId ] ;
251252
253+ int restarts = 0 ;
254+ int restartsToGo = restartInterval ;
255+
252256 for ( int i = 0 ; i < h ; i ++ )
253257 {
254258 cancellationToken . ThrowIfCancellationRequested ( ) ;
@@ -258,6 +262,13 @@ public void EncodeDcScan(Component component, CancellationToken cancellationToke
258262
259263 for ( nuint k = 0 ; k < ( uint ) w ; k ++ )
260264 {
265+ if ( restartInterval > 0 && restartsToGo == 0 )
266+ {
267+ this . FlushRemainingBytes ( ) ;
268+ this . WriteRestart ( restarts % 8 ) ;
269+ component . DcPredictor = 0 ;
270+ }
271+
261272 this . WriteDc (
262273 component ,
263274 ref Unsafe . Add ( ref blockRef , k ) ,
@@ -267,6 +278,18 @@ ref Unsafe.Add(ref blockRef, k),
267278 {
268279 this . FlushToStream ( ) ;
269280 }
281+
282+ if ( restartInterval > 0 )
283+ {
284+ if ( restartsToGo == 0 )
285+ {
286+ restartsToGo = restartInterval ;
287+ restarts ++ ;
288+ restarts &= 7 ;
289+ }
290+
291+ restartsToGo -- ;
292+ }
270293 }
271294 }
272295
@@ -279,12 +302,16 @@ ref Unsafe.Add(ref blockRef, k),
279302 /// <param name="component">The component whose AC coefficients need to be encoded.</param>
280303 /// <param name="start">The starting index of the AC coefficient range to encode.</param>
281304 /// <param name="end">The ending index of the AC coefficient range to encode.</param>
305+ /// <param name="restartInterval">Numbers of MCUs between restart markers.</param>
282306 /// <param name="cancellationToken">The token to request cancellation.</param>
283- public void EncodeAcScan ( Component component , nint start , nint end , CancellationToken cancellationToken )
307+ public void EncodeAcScan ( Component component , nint start , nint end , int restartInterval , CancellationToken cancellationToken )
284308 {
285309 int h = component . HeightInBlocks ;
286310 int w = component . WidthInBlocks ;
287311
312+ int restarts = 0 ;
313+ int restartsToGo = restartInterval ;
314+
288315 ref HuffmanLut acHuffmanTable = ref this . acHuffmanTables [ component . AcTableId ] ;
289316
290317 for ( int i = 0 ; i < h ; i ++ )
@@ -296,6 +323,12 @@ public void EncodeAcScan(Component component, nint start, nint end, Cancellation
296323
297324 for ( nuint k = 0 ; k < ( uint ) w ; k ++ )
298325 {
326+ if ( restartInterval > 0 && restartsToGo == 0 )
327+ {
328+ this . FlushRemainingBytes ( ) ;
329+ this . WriteRestart ( restarts % 8 ) ;
330+ }
331+
299332 this . WriteAcBlock (
300333 ref Unsafe . Add ( ref blockRef , k ) ,
301334 start ,
@@ -306,6 +339,18 @@ ref Unsafe.Add(ref blockRef, k),
306339 {
307340 this . FlushToStream ( ) ;
308341 }
342+
343+ if ( restartInterval > 0 )
344+ {
345+ if ( restartsToGo == 0 )
346+ {
347+ restartsToGo = restartInterval ;
348+ restarts ++ ;
349+ restarts &= 7 ;
350+ }
351+
352+ restartsToGo -- ;
353+ }
309354 }
310355 }
311356
@@ -508,6 +553,9 @@ private void WriteBlock(
508553 this . WriteAcBlock ( ref block , 1 , 64 , ref acTable ) ;
509554 }
510555
556+ private void WriteRestart ( int restart ) =>
557+ this . target . Write ( [ 0xff , ( byte ) ( JpegConstants . Markers . RST0 + restart ) ] ) ;
558+
511559 /// <summary>
512560 /// Emits the most significant count of bits to the buffer.
513561 /// </summary>
0 commit comments