@@ -86,42 +86,39 @@ protected override void OnFrameApply(ImageFrame<TPixel> source)
8686 new Rectangle ( 0 , 0 , sourceWidth , tileYStartPositions . Count ) ,
8787 in operation ) ;
8888
89- ref TPixel pixelsBase = ref source . GetPixelReference ( 0 , 0 ) ;
90-
9189 // Fix left column
92- ProcessBorderColumn ( ref pixelsBase , cdfData , 0 , sourceWidth , sourceHeight , this . Tiles , tileHeight , xStart : 0 , xEnd : halfTileWidth , luminanceLevels ) ;
90+ ProcessBorderColumn ( source , cdfData , 0 , sourceHeight , this . Tiles , tileHeight , xStart : 0 , xEnd : halfTileWidth , luminanceLevels ) ;
9391
9492 // Fix right column
9593 int rightBorderStartX = ( ( this . Tiles - 1 ) * tileWidth ) + halfTileWidth ;
96- ProcessBorderColumn ( ref pixelsBase , cdfData , this . Tiles - 1 , sourceWidth , sourceHeight , this . Tiles , tileHeight , xStart : rightBorderStartX , xEnd : sourceWidth , luminanceLevels ) ;
94+ ProcessBorderColumn ( source , cdfData , this . Tiles - 1 , sourceHeight , this . Tiles , tileHeight , xStart : rightBorderStartX , xEnd : sourceWidth , luminanceLevels ) ;
9795
9896 // Fix top row
99- ProcessBorderRow ( ref pixelsBase , cdfData , 0 , sourceWidth , this . Tiles , tileWidth , yStart : 0 , yEnd : halfTileHeight , luminanceLevels ) ;
97+ ProcessBorderRow ( source , cdfData , 0 , sourceWidth , this . Tiles , tileWidth , yStart : 0 , yEnd : halfTileHeight , luminanceLevels ) ;
10098
10199 // Fix bottom row
102100 int bottomBorderStartY = ( ( this . Tiles - 1 ) * tileHeight ) + halfTileHeight ;
103- ProcessBorderRow ( ref pixelsBase , cdfData , this . Tiles - 1 , sourceWidth , this . Tiles , tileWidth , yStart : bottomBorderStartY , yEnd : sourceHeight , luminanceLevels ) ;
101+ ProcessBorderRow ( source , cdfData , this . Tiles - 1 , sourceWidth , this . Tiles , tileWidth , yStart : bottomBorderStartY , yEnd : sourceHeight , luminanceLevels ) ;
104102
105103 // Left top corner
106- ProcessCornerTile ( ref pixelsBase , cdfData , sourceWidth , 0 , 0 , xStart : 0 , xEnd : halfTileWidth , yStart : 0 , yEnd : halfTileHeight , luminanceLevels ) ;
104+ ProcessCornerTile ( source , cdfData , 0 , 0 , xStart : 0 , xEnd : halfTileWidth , yStart : 0 , yEnd : halfTileHeight , luminanceLevels ) ;
107105
108106 // Left bottom corner
109- ProcessCornerTile ( ref pixelsBase , cdfData , sourceWidth , 0 , this . Tiles - 1 , xStart : 0 , xEnd : halfTileWidth , yStart : bottomBorderStartY , yEnd : sourceHeight , luminanceLevels ) ;
107+ ProcessCornerTile ( source , cdfData , 0 , this . Tiles - 1 , xStart : 0 , xEnd : halfTileWidth , yStart : bottomBorderStartY , yEnd : sourceHeight , luminanceLevels ) ;
110108
111109 // Right top corner
112- ProcessCornerTile ( ref pixelsBase , cdfData , sourceWidth , this . Tiles - 1 , 0 , xStart : rightBorderStartX , xEnd : sourceWidth , yStart : 0 , yEnd : halfTileHeight , luminanceLevels ) ;
110+ ProcessCornerTile ( source , cdfData , this . Tiles - 1 , 0 , xStart : rightBorderStartX , xEnd : sourceWidth , yStart : 0 , yEnd : halfTileHeight , luminanceLevels ) ;
113111
114112 // Right bottom corner
115- ProcessCornerTile ( ref pixelsBase , cdfData , sourceWidth , this . Tiles - 1 , this . Tiles - 1 , xStart : rightBorderStartX , xEnd : sourceWidth , yStart : bottomBorderStartY , yEnd : sourceHeight , luminanceLevels ) ;
113+ ProcessCornerTile ( source , cdfData , this . Tiles - 1 , this . Tiles - 1 , xStart : rightBorderStartX , xEnd : sourceWidth , yStart : bottomBorderStartY , yEnd : sourceHeight , luminanceLevels ) ;
116114 }
117115 }
118116
119117 /// <summary>
120118 /// Processes the part of a corner tile which was previously left out. It consists of 1 / 4 of a tile and does not need interpolation.
121119 /// </summary>
122- /// <param name="pixelsBase ">The output pixels base reference .</param>
120+ /// <param name="source ">The source image .</param>
123121 /// <param name="cdfData">The lookup table to remap the grey values.</param>
124- /// <param name="sourceWidth">The source image width.</param>
125122 /// <param name="cdfX">The x-position in the CDF lookup map.</param>
126123 /// <param name="cdfY">The y-position in the CDF lookup map.</param>
127124 /// <param name="xStart">X start position.</param>
@@ -133,9 +130,8 @@ protected override void OnFrameApply(ImageFrame<TPixel> source)
133130 /// or 65536 for 16-bit grayscale images.
134131 /// </param>
135132 private static void ProcessCornerTile (
136- ref TPixel pixelsBase ,
133+ ImageFrame < TPixel > source ,
137134 CdfTileData cdfData ,
138- int sourceWidth ,
139135 int cdfX ,
140136 int cdfY ,
141137 int xStart ,
@@ -146,10 +142,10 @@ private static void ProcessCornerTile(
146142 {
147143 for ( int dy = yStart ; dy < yEnd ; dy ++ )
148144 {
149- int dyOffSet = dy * sourceWidth ;
145+ Span < TPixel > rowSpan = source . GetPixelRowSpan ( dy ) ;
150146 for ( int dx = xStart ; dx < xEnd ; dx ++ )
151147 {
152- ref TPixel pixel = ref Unsafe . Add ( ref pixelsBase , dyOffSet + dx ) ;
148+ ref TPixel pixel = ref rowSpan [ dx ] ;
153149 float luminanceEqualized = cdfData . RemapGreyValue ( cdfX , cdfY , GetLuminance ( pixel , luminanceLevels ) ) ;
154150 pixel . FromVector4 ( new Vector4 ( luminanceEqualized , luminanceEqualized , luminanceEqualized , pixel . ToVector4 ( ) . W ) ) ;
155151 }
@@ -159,10 +155,9 @@ private static void ProcessCornerTile(
159155 /// <summary>
160156 /// Processes a border column of the image which is half the size of the tile width.
161157 /// </summary>
162- /// <param name="pixelBase ">The output pixels reference .</param>
158+ /// <param name="source ">The source image .</param>
163159 /// <param name="cdfData">The pre-computed lookup tables to remap the grey values for each tiles.</param>
164160 /// <param name="cdfX">The X index of the lookup table to use.</param>
165- /// <param name="sourceWidth">The source image width.</param>
166161 /// <param name="sourceHeight">The source image height.</param>
167162 /// <param name="tileCount">The number of vertical tiles.</param>
168163 /// <param name="tileHeight">The height of a tile.</param>
@@ -173,10 +168,9 @@ private static void ProcessCornerTile(
173168 /// or 65536 for 16-bit grayscale images.
174169 /// </param>
175170 private static void ProcessBorderColumn (
176- ref TPixel pixelBase ,
171+ ImageFrame < TPixel > source ,
177172 CdfTileData cdfData ,
178173 int cdfX ,
179- int sourceWidth ,
180174 int sourceHeight ,
181175 int tileCount ,
182176 int tileHeight ,
@@ -194,10 +188,10 @@ private static void ProcessBorderColumn(
194188 int tileY = 0 ;
195189 for ( int dy = y ; dy < yLimit ; dy ++ )
196190 {
197- int dyOffSet = dy * sourceWidth ;
191+ Span < TPixel > rowSpan = source . GetPixelRowSpan ( dy ) ;
198192 for ( int dx = xStart ; dx < xEnd ; dx ++ )
199193 {
200- ref TPixel pixel = ref Unsafe . Add ( ref pixelBase , dyOffSet + dx ) ;
194+ ref TPixel pixel = ref rowSpan [ dx ] ;
201195 float luminanceEqualized = InterpolateBetweenTwoTiles ( pixel , cdfData , cdfX , cdfY , cdfX , cdfY + 1 , tileY , tileHeight , luminanceLevels ) ;
202196 pixel . FromVector4 ( new Vector4 ( luminanceEqualized , luminanceEqualized , luminanceEqualized , pixel . ToVector4 ( ) . W ) ) ;
203197 }
@@ -213,7 +207,7 @@ private static void ProcessBorderColumn(
213207 /// <summary>
214208 /// Processes a border row of the image which is half of the size of the tile height.
215209 /// </summary>
216- /// <param name="pixelBase ">The output pixels base reference .</param>
210+ /// <param name="source ">The source image .</param>
217211 /// <param name="cdfData">The pre-computed lookup tables to remap the grey values for each tiles.</param>
218212 /// <param name="cdfY">The Y index of the lookup table to use.</param>
219213 /// <param name="sourceWidth">The source image width.</param>
@@ -226,7 +220,7 @@ private static void ProcessBorderColumn(
226220 /// or 65536 for 16-bit grayscale images.
227221 /// </param>
228222 private static void ProcessBorderRow (
229- ref TPixel pixelBase ,
223+ ImageFrame < TPixel > source ,
230224 CdfTileData cdfData ,
231225 int cdfY ,
232226 int sourceWidth ,
@@ -244,12 +238,12 @@ private static void ProcessBorderRow(
244238 {
245239 for ( int dy = yStart ; dy < yEnd ; dy ++ )
246240 {
247- int dyOffSet = dy * sourceWidth ;
241+ Span < TPixel > rowSpan = source . GetPixelRowSpan ( dy ) ;
248242 int tileX = 0 ;
249243 int xLimit = Math . Min ( x + tileWidth , sourceWidth - 1 ) ;
250244 for ( int dx = x ; dx < xLimit ; dx ++ )
251245 {
252- ref TPixel pixel = ref Unsafe . Add ( ref pixelBase , dyOffSet + dx ) ;
246+ ref TPixel pixel = ref rowSpan [ dx ] ;
253247 float luminanceEqualized = InterpolateBetweenTwoTiles ( pixel , cdfData , cdfX , cdfY , cdfX + 1 , cdfY , tileX , tileWidth , luminanceLevels ) ;
254248 pixel . FromVector4 ( new Vector4 ( luminanceEqualized , luminanceEqualized , luminanceEqualized , pixel . ToVector4 ( ) . W ) ) ;
255249 tileX ++ ;
@@ -410,8 +404,6 @@ public RowIntervalOperation(
410404 [ MethodImpl ( InliningOptions . ShortMethod ) ]
411405 public void Invoke ( in RowInterval rows )
412406 {
413- ref TPixel sourceBase = ref this . source . GetPixelReference ( 0 , 0 ) ;
414-
415407 for ( int index = rows . Min ; index < rows . Max ; index ++ )
416408 {
417409 ( int y , int cdfY ) tileYStartPosition = this . tileYStartPositions [ index ] ;
@@ -427,11 +419,11 @@ public void Invoke(in RowInterval rows)
427419 int xEnd = Math . Min ( x + this . tileWidth , this . sourceWidth ) ;
428420 for ( int dy = y ; dy < yEnd ; dy ++ )
429421 {
430- int dyOffSet = dy * this . sourceWidth ;
422+ Span < TPixel > rowSpan = this . source . GetPixelRowSpan ( dy ) ;
431423 int tileX = 0 ;
432424 for ( int dx = x ; dx < xEnd ; dx ++ )
433425 {
434- ref TPixel pixel = ref Unsafe . Add ( ref sourceBase , dyOffSet + dx ) ;
426+ ref TPixel pixel = ref rowSpan [ dx ] ;
435427 float luminanceEqualized = InterpolateBetweenFourTiles (
436428 pixel ,
437429 this . cdfData ,
@@ -597,15 +589,13 @@ public RowIntervalOperation(
597589 [ MethodImpl ( InliningOptions . ShortMethod ) ]
598590 public void Invoke ( in RowInterval rows )
599591 {
600- ref TPixel sourceBase = ref this . source . GetPixelReference ( 0 , 0 ) ;
601-
602592 for ( int index = rows . Min ; index < rows . Max ; index ++ )
603593 {
604594 int cdfX = 0 ;
605595 int cdfY = this . tileYStartPositions [ index ] . cdfY ;
606596 int y = this . tileYStartPositions [ index ] . y ;
607597 int endY = Math . Min ( y + this . tileHeight , this . sourceHeight ) ;
608- ref int cdfMinBase = ref MemoryMarshal . GetReference ( this . cdfMinBuffer2D . GetRowSpan ( cdfY ) ) ;
598+ Span < int > cdfMinSpan = this . cdfMinBuffer2D . GetRowSpan ( cdfY ) ;
609599
610600 using IMemoryOwner < int > histogramBuffer = this . allocator . Allocate < int > ( this . luminanceLevels ) ;
611601 Span < int > histogram = histogramBuffer . GetSpan ( ) ;
@@ -620,10 +610,10 @@ public void Invoke(in RowInterval rows)
620610 int xlimit = Math . Min ( x + this . tileWidth , this . sourceWidth ) ;
621611 for ( int dy = y ; dy < endY ; dy ++ )
622612 {
623- int dyOffset = dy * this . sourceWidth ;
613+ Span < TPixel > rowSpan = this . source . GetPixelRowSpan ( dy ) ;
624614 for ( int dx = x ; dx < xlimit ; dx ++ )
625615 {
626- int luminance = GetLuminance ( Unsafe . Add ( ref sourceBase , dyOffset + dx ) , this . luminanceLevels ) ;
616+ int luminance = GetLuminance ( rowSpan [ dx ] , this . luminanceLevels ) ;
627617 histogram [ luminance ] ++ ;
628618 }
629619 }
@@ -633,7 +623,7 @@ public void Invoke(in RowInterval rows)
633623 this . processor . ClipHistogram ( histogram , this . processor . ClipLimit ) ;
634624 }
635625
636- Unsafe . Add ( ref cdfMinBase , cdfX ) = this . processor . CalculateCdf ( ref cdfBase , ref histogramBase , histogram . Length - 1 ) ;
626+ cdfMinSpan [ cdfX ] + = this . processor . CalculateCdf ( ref cdfBase , ref histogramBase , histogram . Length - 1 ) ;
637627
638628 cdfX ++ ;
639629 }
0 commit comments