|
|
|
@ -70,88 +70,88 @@ namespace ImageSharp.Processing.Processors |
|
|
|
} |
|
|
|
|
|
|
|
using (PixelAccessor<TPixel> targetPixels = new PixelAccessor<TPixel>(source.Width, source.Height)) |
|
|
|
using (PixelAccessor<TPixel> sourcePixels = source.Lock()) |
|
|
|
{ |
|
|
|
using (PixelAccessor<TPixel> sourcePixels = source.Lock()) |
|
|
|
{ |
|
|
|
Parallel.For( |
|
|
|
minY, |
|
|
|
maxY, |
|
|
|
this.ParallelOptions, |
|
|
|
y => |
|
|
|
sourcePixels.CopyTo(targetPixels); |
|
|
|
|
|
|
|
Parallel.For( |
|
|
|
minY, |
|
|
|
maxY, |
|
|
|
this.ParallelOptions, |
|
|
|
y => |
|
|
|
{ |
|
|
|
for (int x = startX; x < endX; x++) |
|
|
|
{ |
|
|
|
for (int x = startX; x < endX; x++) |
|
|
|
int maxIntensity = 0; |
|
|
|
int maxIndex = 0; |
|
|
|
|
|
|
|
int[] intensityBin = new int[levels]; |
|
|
|
float[] redBin = new float[levels]; |
|
|
|
float[] blueBin = new float[levels]; |
|
|
|
float[] greenBin = new float[levels]; |
|
|
|
|
|
|
|
for (int fy = 0; fy <= radius; fy++) |
|
|
|
{ |
|
|
|
int maxIntensity = 0; |
|
|
|
int maxIndex = 0; |
|
|
|
int fyr = fy - radius; |
|
|
|
int offsetY = y + fyr; |
|
|
|
|
|
|
|
int[] intensityBin = new int[levels]; |
|
|
|
float[] redBin = new float[levels]; |
|
|
|
float[] blueBin = new float[levels]; |
|
|
|
float[] greenBin = new float[levels]; |
|
|
|
// Skip the current row
|
|
|
|
if (offsetY < minY) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
for (int fy = 0; fy <= radius; fy++) |
|
|
|
// Outwith the current bounds so break.
|
|
|
|
if (offsetY >= maxY) |
|
|
|
{ |
|
|
|
int fyr = fy - radius; |
|
|
|
int offsetY = y + fyr; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
// Skip the current row
|
|
|
|
if (offsetY < minY) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
for (int fx = 0; fx <= radius; fx++) |
|
|
|
{ |
|
|
|
int fxr = fx - radius; |
|
|
|
int offsetX = x + fxr; |
|
|
|
|
|
|
|
// Outwith the current bounds so break.
|
|
|
|
if (offsetY >= maxY) |
|
|
|
// Skip the column
|
|
|
|
if (offsetX < 0) |
|
|
|
{ |
|
|
|
break; |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
for (int fx = 0; fx <= radius; fx++) |
|
|
|
if (offsetX < maxX) |
|
|
|
{ |
|
|
|
int fxr = fx - radius; |
|
|
|
int offsetX = x + fxr; |
|
|
|
// ReSharper disable once AccessToDisposedClosure
|
|
|
|
Vector4 color = sourcePixels[offsetX, offsetY].ToVector4(); |
|
|
|
|
|
|
|
// Skip the column
|
|
|
|
if (offsetX < 0) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (offsetX < maxX) |
|
|
|
{ |
|
|
|
// ReSharper disable once AccessToDisposedClosure
|
|
|
|
Vector4 color = sourcePixels[offsetX, offsetY].ToVector4(); |
|
|
|
float sourceRed = color.X; |
|
|
|
float sourceBlue = color.Z; |
|
|
|
float sourceGreen = color.Y; |
|
|
|
|
|
|
|
float sourceRed = color.X; |
|
|
|
float sourceBlue = color.Z; |
|
|
|
float sourceGreen = color.Y; |
|
|
|
int currentIntensity = (int)Math.Round((sourceBlue + sourceGreen + sourceRed) / 3.0 * (levels - 1)); |
|
|
|
|
|
|
|
int currentIntensity = (int)Math.Round((sourceBlue + sourceGreen + sourceRed) / 3.0 * (levels - 1)); |
|
|
|
intensityBin[currentIntensity] += 1; |
|
|
|
blueBin[currentIntensity] += sourceBlue; |
|
|
|
greenBin[currentIntensity] += sourceGreen; |
|
|
|
redBin[currentIntensity] += sourceRed; |
|
|
|
|
|
|
|
intensityBin[currentIntensity] += 1; |
|
|
|
blueBin[currentIntensity] += sourceBlue; |
|
|
|
greenBin[currentIntensity] += sourceGreen; |
|
|
|
redBin[currentIntensity] += sourceRed; |
|
|
|
|
|
|
|
if (intensityBin[currentIntensity] > maxIntensity) |
|
|
|
{ |
|
|
|
maxIntensity = intensityBin[currentIntensity]; |
|
|
|
maxIndex = currentIntensity; |
|
|
|
} |
|
|
|
if (intensityBin[currentIntensity] > maxIntensity) |
|
|
|
{ |
|
|
|
maxIntensity = intensityBin[currentIntensity]; |
|
|
|
maxIndex = currentIntensity; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
float red = MathF.Abs(redBin[maxIndex] / maxIntensity); |
|
|
|
float green = MathF.Abs(greenBin[maxIndex] / maxIntensity); |
|
|
|
float blue = MathF.Abs(blueBin[maxIndex] / maxIntensity); |
|
|
|
float red = MathF.Abs(redBin[maxIndex] / maxIntensity); |
|
|
|
float green = MathF.Abs(greenBin[maxIndex] / maxIntensity); |
|
|
|
float blue = MathF.Abs(blueBin[maxIndex] / maxIntensity); |
|
|
|
|
|
|
|
TPixel packed = default(TPixel); |
|
|
|
packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); |
|
|
|
targetPixels[x, y] = packed; |
|
|
|
} |
|
|
|
TPixel packed = default(TPixel); |
|
|
|
packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W)); |
|
|
|
targetPixels[x, y] = packed; |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
source.SwapPixelsBuffers(targetPixels); |
|
|
|
} |
|
|
|
|