33
44using System ;
55using System . Buffers ;
6+ using System . Linq ;
67using System . Numerics ;
78using System . Threading ;
89using SixLabors . ImageSharp . Formats . Jpeg . Components . Decoder . ColorConverters ;
@@ -29,8 +30,6 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
2930
3031 private Buffer2D < TPixel > pixelBuffer ;
3132
32- private int blockRowsPerStep ;
33-
3433 private int pixelRowsPerStep ;
3534
3635 private int pixelRowCounter ;
@@ -41,8 +40,6 @@ public SpectralConverter(Configuration configuration, CancellationToken cancella
4140 this . cancellationToken = cancellationToken ;
4241 }
4342
44- private bool Converted => this . pixelRowCounter >= this . pixelBuffer . Height ;
45-
4643 public Buffer2D < TPixel > GetPixelBuffer ( )
4744 {
4845 if ( ! this . Converted )
@@ -52,7 +49,7 @@ public Buffer2D<TPixel> GetPixelBuffer()
5249 for ( int step = 0 ; step < steps ; step ++ )
5350 {
5451 this . cancellationToken . ThrowIfCancellationRequested ( ) ;
55- this . ConvertNextStride ( step ) ;
52+ this . ConvertStride ( step ) ;
5653 }
5754 }
5855
@@ -65,26 +62,26 @@ public override void InjectFrameData(JpegFrame frame, IRawJpegData jpegData)
6562 MemoryAllocator allocator = this . configuration . MemoryAllocator ;
6663
6764 // iteration data
68- IJpegComponent c0 = frame . Components [ 0 ] ;
65+ int majorBlockWidth = frame . Components . Max ( ( component ) => component . SizeInBlocks . Width ) ;
66+ int majorVerticalSamplingFactor = frame . Components . Max ( ( component ) => component . SamplingFactors . Height ) ;
6967
7068 const int blockPixelHeight = 8 ;
71- this . blockRowsPerStep = c0 . SamplingFactors . Height ;
72- this . pixelRowsPerStep = this . blockRowsPerStep * blockPixelHeight ;
69+ this . pixelRowsPerStep = majorVerticalSamplingFactor * blockPixelHeight ;
7370
7471 // pixel buffer for resulting image
7572 this . pixelBuffer = allocator . Allocate2D < TPixel > ( frame . PixelWidth , frame . PixelHeight ) ;
7673 this . paddedProxyPixelRow = allocator . Allocate < TPixel > ( frame . PixelWidth + 3 ) ;
7774
7875 // component processors from spectral to Rgba32
79- var postProcessorBufferSize = new Size ( c0 . SizeInBlocks . Width * 8 , this . pixelRowsPerStep ) ;
76+ const int blockPixelWidth = 8 ;
77+ var postProcessorBufferSize = new Size ( majorBlockWidth * blockPixelWidth , this . pixelRowsPerStep ) ;
8078 this . componentProcessors = new JpegComponentPostProcessor [ frame . Components . Length ] ;
8179 for ( int i = 0 ; i < this . componentProcessors . Length ; i ++ )
8280 {
8381 this . componentProcessors [ i ] = new JpegComponentPostProcessor ( allocator , frame , jpegData , postProcessorBufferSize , frame . Components [ i ] ) ;
8482 }
8583
8684 // single 'stride' rgba32 buffer for conversion between spectral and TPixel
87- // this.rgbaBuffer = allocator.Allocate<Vector4>(frame.PixelWidth);
8885 this . rgbBuffer = allocator . Allocate < byte > ( frame . PixelWidth * 3 ) ;
8986
9087 // color converter from Rgba32 to TPixel
@@ -95,18 +92,17 @@ public override void InjectFrameData(JpegFrame frame, IRawJpegData jpegData)
9592 public override void ConvertStrideBaseline ( )
9693 {
9794 // Convert next pixel stride using single spectral `stride'
98- // Note that zero passing eliminates the need of virtual call from JpegComponentPostProcessor
99- this . ConvertNextStride ( spectralStep : 0 ) ;
95+ // Note that zero passing eliminates the need of virtual call
96+ // from JpegComponentPostProcessor
97+ this . ConvertStride ( spectralStep : 0 ) ;
10098
101- // Clear spectral stride - this is VERY important as jpeg possibly won't fill entire buffer each stride
102- // Which leads to decoding artifacts
103- // Note that this code clears all buffers of the post processors, it's their responsibility to allocate only single stride
10499 foreach ( JpegComponentPostProcessor cpp in this . componentProcessors )
105100 {
106101 cpp . ClearSpectralBuffers ( ) ;
107102 }
108103 }
109104
105+ /// <inheritdoc/>
110106 public void Dispose ( )
111107 {
112108 if ( this . componentProcessors != null )
@@ -121,7 +117,7 @@ public void Dispose()
121117 this . paddedProxyPixelRow ? . Dispose ( ) ;
122118 }
123119
124- private void ConvertNextStride ( int spectralStep )
120+ private void ConvertStride ( int spectralStep )
125121 {
126122 int maxY = Math . Min ( this . pixelBuffer . Height , this . pixelRowCounter + this . pixelRowsPerStep ) ;
127123
0 commit comments