static unsafe void VerticalBoxBlur(ref UnmanagedImage image, Rectangle rect, IntRange kernelSizeRange)
{
var pixelSize = ((image.PixelFormat == PixelFormat.Format8bppIndexed) ||
(image.PixelFormat == PixelFormat.Format16bppGrayScale)) ? 1 : 3;
var startY = rect.Top;
var stopY = startY + rect.Height;
var startX = rect.Left * pixelSize;
var stopX = startX + rect.Width * pixelSize;
var basePtr = (byte*)image.ImageData.ToPointer();
if ((image.PixelFormat == PixelFormat.Format8bppIndexed) ||
(image.PixelFormat == PixelFormat.Format24bppRgb))
{
var offset = image.Stride - (stopX - startX);
// align pointer to the first pixel to process
var ptr = basePtr + (startY * image.Stride + rect.Left * pixelSize);
for (var y = startY; y < stopY; y++)
{
for (var x = startX; x < stopX; x++, ptr++)
{
var sum = 0;
for (var yFilter = kernelSizeRange.Min; yFilter < kernelSizeRange.Max; yFilter++)
{
var yBound = y + yFilter;
//Only if in bounds
if (yBound < 0 || yBound >= image.Height)
continue;
sum += ptr[yFilter * image.Stride];
}
*ptr = (byte)(sum / kernelSizeRange.Length);
}
ptr += offset;
}
}
else
{
// align pointer to the first pixel to process
basePtr += (startY * image.Stride + rect.Left * pixelSize * 2);
for (var y = startY; y < stopY; y++)
{
var ptr = (ushort*)(basePtr);
for (var x = startX; x < stopX; x++, ptr++)
{
var sum = 0;
for (var yFilter = kernelSizeRange.Min; yFilter < kernelSizeRange.Max; yFilter++)
{
var yBound = y + yFilter;
//Only if in bounds
if (yBound < 0 || yBound >= image.Height)
continue;
sum += ptr[yFilter * image.Stride / 2];
}
*ptr = (ushort)(sum / kernelSizeRange.Length);
}
basePtr += image.Stride;
}
}
}
}