@@ -52,7 +52,7 @@ internal ScanDecoder(FrameInfo frameInfo, JpegLSPresetCodingParameters presetCod
5252
5353 private readonly int PixelStride => FrameInfo . Width + 2 ;
5454
55- internal int DecodeScan ( ReadOnlyMemory < byte > source , Span < byte > destination , int stride )
55+ internal int DecodeScan ( ReadOnlyMemory < byte > source , Span < byte > destination , int stride , Span < int > widths , Span < int > heights )
5656 {
5757 Initialize ( source ) ;
5858
@@ -61,11 +61,11 @@ internal int DecodeScan(ReadOnlyMemory<byte> source, Span<byte> destination, int
6161
6262 if ( FrameInfo . BitsPerSample <= 8 )
6363 {
64- DecodeLines8Bit ( destination , stride ) ;
64+ DecodeLines8Bit ( destination , stride , widths , heights ) ;
6565 }
6666 else
6767 {
68- DecodeLines16Bit ( destination , stride ) ;
68+ DecodeLines16Bit ( destination , stride , widths ) ;
6969 }
7070
7171 EndScan ( ) ;
@@ -352,7 +352,7 @@ private bool FillReadCacheOptimistic()
352352 return true ;
353353 }
354354
355- private void DecodeLines8Bit ( Span < byte > destination , int stride )
355+ private void DecodeLines8Bit ( Span < byte > destination , int stride , Span < int > widths , Span < int > heights )
356356 {
357357 switch ( CodingParameters . InterleaveMode )
358358 {
@@ -361,7 +361,7 @@ private void DecodeLines8Bit(Span<byte> destination, int stride)
361361 break ;
362362
363363 case InterleaveMode . Line :
364- DecodeLines8BitInterleaveModeLine ( destination , stride ) ;
364+ DecodeLines8BitInterleaveModeLine ( destination , stride , widths , heights ) ;
365365 break ;
366366
367367 case InterleaveMode . Sample :
@@ -382,7 +382,7 @@ private void DecodeLines8Bit(Span<byte> destination, int stride)
382382 }
383383 }
384384
385- private void DecodeLines16Bit ( Span < byte > destination , int stride )
385+ private void DecodeLines16Bit ( Span < byte > destination , int stride , Span < int > widths )
386386 {
387387 switch ( CodingParameters . InterleaveMode )
388388 {
@@ -391,7 +391,7 @@ private void DecodeLines16Bit(Span<byte> destination, int stride)
391391 break ;
392392
393393 case InterleaveMode . Line :
394- DecodeLines16BitInterleaveModeLine ( destination , stride ) ;
394+ DecodeLines16BitInterleaveModeLine ( destination , stride , widths ) ;
395395 break ;
396396
397397 case InterleaveMode . Sample :
@@ -438,7 +438,7 @@ private void DecodeLines8BitInterleaveModeNone(Span<byte> destination, int strid
438438 previousLine [ FrameInfo . Width + 1 ] = previousLine [ FrameInfo . Width ] ;
439439 currentLine [ 0 ] = previousLine [ 1 ] ;
440440
441- DecodeSampleLine ( previousLine , currentLine ) ;
441+ DecodeSampleLine ( previousLine , currentLine , FrameInfo . Width ) ;
442442
443443 CopyLineBufferToDestinationInterleaveNone ( currentLine [ 1 ..] , destination , FrameInfo . Width ) ;
444444
@@ -489,7 +489,7 @@ private void DecodeLines16BitInterleaveModeNone(Span<byte> destination, int stri
489489 previousLine [ FrameInfo . Width + 1 ] = previousLine [ FrameInfo . Width ] ;
490490 currentLine [ 0 ] = previousLine [ 1 ] ;
491491
492- DecodeSampleLine ( previousLine , currentLine ) ;
492+ DecodeSampleLine ( previousLine , currentLine , FrameInfo . Width ) ;
493493
494494 CopyLineBufferToDestinationInterleaveNone ( currentLine [ 1 ..] , destination , FrameInfo . Width ) ;
495495
@@ -515,7 +515,7 @@ private void DecodeLines16BitInterleaveModeNone(Span<byte> destination, int stri
515515 }
516516 }
517517
518- private void DecodeLines8BitInterleaveModeLine ( Span < byte > destination , int stride )
518+ private void DecodeLines8BitInterleaveModeLine ( Span < byte > destination , int stride , Span < int > widths , Span < int > heights )
519519 {
520520 int pixelStride = FrameInfo . Width + 2 ;
521521 int componentCount = FrameInfo . ComponentCount ;
@@ -544,10 +544,13 @@ private void DecodeLines8BitInterleaveModeLine(Span<byte> destination, int strid
544544 _scanCodec . RunIndex = runIndex [ component ] ;
545545
546546 // Initialize edge pixels used for prediction
547- previousLine [ FrameInfo . Width + 1 ] = previousLine [ FrameInfo . Width ] ;
547+ previousLine [ widths [ component ] + 1 ] = previousLine [ widths [ component ] ] ;
548548 currentLine [ 0 ] = previousLine [ 1 ] ;
549549
550- DecodeSampleLine ( previousLine , currentLine ) ;
550+ if ( line + mcu < heights [ component ] )
551+ {
552+ DecodeSampleLine ( previousLine , currentLine , widths [ component ] ) ;
553+ }
551554
552555 runIndex [ component ] = _scanCodec . RunIndex ;
553556 currentLine = currentLine [ pixelStride ..] ;
@@ -580,7 +583,7 @@ private void DecodeLines8BitInterleaveModeLine(Span<byte> destination, int strid
580583 }
581584 }
582585
583- private void DecodeLines16BitInterleaveModeLine ( Span < byte > destination , int stride )
586+ private void DecodeLines16BitInterleaveModeLine ( Span < byte > destination , int stride , Span < int > widths )
584587 {
585588 int pixelStride = FrameInfo . Width + 2 ;
586589 int componentCount = FrameInfo . ComponentCount ;
@@ -612,7 +615,7 @@ private void DecodeLines16BitInterleaveModeLine(Span<byte> destination, int stri
612615 previousLine [ FrameInfo . Width + 1 ] = previousLine [ FrameInfo . Width ] ;
613616 currentLine [ 0 ] = previousLine [ 1 ] ;
614617
615- DecodeSampleLine ( previousLine , currentLine ) ;
618+ DecodeSampleLine ( previousLine , currentLine , widths [ component ] ) ;
616619
617620 runIndex [ component ] = _scanCodec . RunIndex ;
618621 currentLine = currentLine [ pixelStride ..] ;
@@ -957,13 +960,13 @@ private readonly int QuantizeGradient(int di)
957960 return _scanCodec . QuantizationLut [ ( _scanCodec . QuantizationLut . Length / 2 ) + di ] ;
958961 }
959962
960- private void DecodeSampleLine ( Span < byte > previousLine , Span < byte > currentLine )
963+ private void DecodeSampleLine ( Span < byte > previousLine , Span < byte > currentLine , int width )
961964 {
962965 int index = 1 ;
963966 int rb = previousLine [ 0 ] ;
964967 int rd = previousLine [ index ] ;
965968
966- while ( index <= FrameInfo . Width )
969+ while ( index <= width )
967970 {
968971 int ra = currentLine [ index - 1 ] ;
969972 int rc = rb ;
@@ -974,7 +977,7 @@ private void DecodeSampleLine(Span<byte> previousLine, Span<byte> currentLine)
974977 QuantizeGradient ( rd - rb ) , QuantizeGradient ( rb - rc ) , QuantizeGradient ( rc - ra ) ) ;
975978 if ( qs == 0 )
976979 {
977- index += DecodeRunMode ( index , previousLine , currentLine ) ;
980+ index += DecodeRunMode ( index , previousLine , currentLine , width ) ;
978981 rb = previousLine [ index - 1 ] ;
979982 rd = previousLine [ index ] ;
980983 }
@@ -986,13 +989,13 @@ private void DecodeSampleLine(Span<byte> previousLine, Span<byte> currentLine)
986989 }
987990 }
988991
989- private void DecodeSampleLine ( Span < ushort > previousLine , Span < ushort > currentLine )
992+ private void DecodeSampleLine ( Span < ushort > previousLine , Span < ushort > currentLine , int width )
990993 {
991994 int index = 1 ;
992995 int rb = previousLine [ 0 ] ;
993996 int rd = previousLine [ index ] ;
994997
995- while ( index <= FrameInfo . Width )
998+ while ( index <= width )
996999 {
9971000 int ra = currentLine [ index - 1 ] ;
9981001 int rc = rb ;
@@ -1236,14 +1239,14 @@ private int DecodeRegular(int qs, int predicted)
12361239 return Traits . ComputeReconstructedSample ( correctedPrediction , errorValue ) ;
12371240 }
12381241
1239- private int DecodeRunMode ( int startIndex , Span < byte > previousLine , Span < byte > currentLine )
1242+ private int DecodeRunMode ( int startIndex , Span < byte > previousLine , Span < byte > currentLine , int width )
12401243 {
12411244 var ra = currentLine [ startIndex - 1 ] ;
12421245
1243- int runLength = DecodeRunPixels ( ra , currentLine [ startIndex ..] , FrameInfo . Width - ( startIndex - 1 ) ) ;
1246+ int runLength = DecodeRunPixels ( ra , currentLine [ startIndex ..] , width - ( startIndex - 1 ) ) ;
12441247 int endIndex = startIndex + runLength ;
12451248
1246- if ( endIndex - 1 == FrameInfo . Width )
1249+ if ( endIndex - 1 == width )
12471250 return endIndex - startIndex ;
12481251
12491252 // Run interruption
0 commit comments