diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs
index d055e8b862..767feb0600 100644
--- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs
@@ -104,6 +104,41 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
// fix bottom row
this.ProcessBorderRow(source, pixels, cdfData, this.Tiles - 1, tileWidth, tileHeight, yStart: source.Height - halfTileHeight, yEnd: source.Height);
+
+ // left top corner
+ this.ProcessCornerTile(source, pixels, cdfData[0, 0], xStart: 0, xEnd: halfTileWidth, yStart: 0, yEnd: halfTileHeight, pixelsInTile: pixelsInTile);
+
+ // left bottom corner
+ this.ProcessCornerTile(source, pixels, cdfData[0, this.Tiles - 1], xStart: 0, xEnd: halfTileWidth, yStart: source.Height - halfTileHeight, yEnd: source.Height, pixelsInTile: pixelsInTile);
+
+ // right top corner
+ this.ProcessCornerTile(source, pixels, cdfData[this.Tiles - 1, 0], xStart: source.Width - halfTileWidth, xEnd: source.Width, yStart: 0, yEnd: halfTileHeight, pixelsInTile: pixelsInTile);
+
+ // right bottom corner
+ this.ProcessCornerTile(source, pixels, cdfData[this.Tiles - 1, this.Tiles - 1], xStart: source.Width - halfTileWidth, xEnd: source.Width, yStart: source.Height - halfTileHeight, yEnd: source.Height, pixelsInTile: pixelsInTile);
+ }
+ }
+
+ ///
+ /// 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.
+ ///
+ /// The source image.
+ /// The output pixels.
+ /// The lookup table to remap the grey values.
+ /// X start position.
+ /// X end position.
+ /// Y start position.
+ /// Y end position.
+ /// Pixels in a tile.
+ private void ProcessCornerTile(ImageFrame source, Span pixels, CdfData cdfData, int xStart, int xEnd, int yStart, int yEnd, int pixelsInTile)
+ {
+ for (int dy = yStart; dy < yEnd; dy++)
+ {
+ for (int dx = xStart; dx < xEnd; dx++)
+ {
+ float luminanceEqualized = cdfData.RemapGreyValue(this.GetLuminance(source[dx, dy], this.LuminanceLevels), pixelsInTile);
+ pixels[(dy * source.Width) + dx].PackFromVector4(new Vector4(luminanceEqualized));
+ }
}
}
@@ -200,7 +235,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// A re-mapped grey value.
private float InterpolateBetweenFourTiles(TPixel sourcePixel, CdfData[,] cdfData, int tileX, int tileY, int cdfX, int cdfY, int tileWidth, int tileHeight, int pixelsInTile)
{
- int luminace = this.GetLuminance(sourcePixel, this.LuminanceLevels);
+ int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels);
float tx = tileX / (float)(tileWidth - 1);
float ty = tileY / (float)(tileHeight - 1);
@@ -209,10 +244,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
int xLeft = cdfX;
int xRight = Math.Min(this.Tiles - 1, xLeft + 1);
- float cdfLeftTopLuminance = cdfData[xLeft, yTop].RemapGreyValue(luminace, pixelsInTile);
- float cdfRightTopLuminance = cdfData[xRight, yTop].RemapGreyValue(luminace, pixelsInTile);
- float cdfLeftBottomLuminance = cdfData[xLeft, yBottom].RemapGreyValue(luminace, pixelsInTile);
- float cdfRightBottomLuminance = cdfData[xRight, yBottom].RemapGreyValue(luminace, pixelsInTile);
+ float cdfLeftTopLuminance = cdfData[xLeft, yTop].RemapGreyValue(luminance, pixelsInTile);
+ float cdfRightTopLuminance = cdfData[xRight, yTop].RemapGreyValue(luminance, pixelsInTile);
+ float cdfLeftBottomLuminance = cdfData[xLeft, yBottom].RemapGreyValue(luminance, pixelsInTile);
+ float cdfRightBottomLuminance = cdfData[xRight, yBottom].RemapGreyValue(luminance, pixelsInTile);
float luminanceEqualized = this.BilinearInterpolation(tx, ty, cdfLeftTopLuminance, cdfRightTopLuminance, cdfLeftBottomLuminance, cdfRightBottomLuminance);
return luminanceEqualized;
@@ -230,11 +265,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// A re-mapped grey value.
private float InterpolateBetweenTwoTiles(TPixel sourcePixel, CdfData cdfData1, CdfData cdfData2, int tilePos, int tileWidth, int pixelsInTile)
{
- int luminace = this.GetLuminance(sourcePixel, this.LuminanceLevels);
+ int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels);
float tx = tilePos / (float)(tileWidth - 1);
- float cdfLuminance1 = cdfData1.RemapGreyValue(luminace, pixelsInTile);
- float cdfLuminance2 = cdfData2.RemapGreyValue(luminace, pixelsInTile);
+ float cdfLuminance1 = cdfData1.RemapGreyValue(luminance, pixelsInTile);
+ float cdfLuminance2 = cdfData2.RemapGreyValue(luminance, pixelsInTile);
float luminanceEqualized = this.LinearInterpolation(cdfLuminance1, cdfLuminance2, tx);
return luminanceEqualized;