protected override unsafe void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
int pixelSize = (image.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3;
// processing start and stop Y positions
int startY = rect.Top;
int stopY = startY + rect.Height;
// processing width and offset
int width = rect.Width;
int offset = image.Stride - width * pixelSize;
// loop indexes and temp vars
int i, j, k, x, t1, t2;
// line length to process
int len = (int)((width - 1) / pixelWidth) + 1;
// reminder
int rem = ((width - 1) % pixelWidth) + 1;
// do the job
byte* src = (byte*)image.ImageData.ToPointer();
// allign pointer to the first pixel to process
src += (startY * image.Stride + rect.Left * pixelSize);
byte* dst = src;
if (image.PixelFormat == PixelFormat.Format8bppIndexed)
{
// Grayscale image
int[] tmp = new int[len];
for (int y1 = startY, y2 = startY; y1 < stopY; )
{
// collect pixels
Array.Clear(tmp, 0, len);
// calculate
for (i = 0; (i < pixelHeight) && (y1 < stopY); i++, y1++)
{
// for each pixel
for (x = 0; x < width; x++, src++)
{
tmp[(int)(x / pixelWidth)] += (int)*src;
}
src += offset;
}
// get average values
t1 = i * pixelWidth;
t2 = i * rem;
for (j = 0; j < len - 1; j++)
tmp[j] /= t1;
tmp[j] /= t2;
// save average value to destination image
for (i = 0; (i < pixelHeight) && (y2 < stopY); i++, y2++)
{
// for each pixel
for (x = 0; x < width; x++, dst++)
{
*dst = (byte)tmp[(int)(x / pixelWidth)];
}
dst += offset;
}
}
}
else
{
// RGB image
int[] tmp = new int[len * 3];
for (int y1 = startY, y2 = startY; y1 < stopY; )
{
// collect pixels
Array.Clear(tmp, 0, len * 3);
// calculate
for (i = 0; (i < pixelHeight) && (y1 < stopY); i++, y1++)
{
// for each pixel
for (x = 0; x < width; x++, src += 3)
{
k = (x / pixelWidth) * 3;
tmp[k] += src[RGB.R];
tmp[k + 1] += src[RGB.G];
tmp[k + 2] += src[RGB.B];
}
src += offset;
}
// get average values
t1 = i * pixelWidth;
t2 = i * rem;
for (j = 0, k = 0; j < len - 1; j++, k += 3)
{
tmp[k] /= t1;
tmp[k + 1] /= t1;
tmp[k + 2] /= t1;
}
tmp[k] /= t2;
tmp[k + 1] /= t2;
tmp[k + 2] /= t2;
// save average value to destination image
for (i = 0; (i < pixelHeight) && (y2 < stopY); i++, y2++)
{
// for each pixel
for (x = 0; x < width; x++, dst += 3)
{
k = (x / pixelWidth) * 3;
dst[RGB.R] = (byte)tmp[k];
dst[RGB.G] = (byte)tmp[k + 1];
dst[RGB.B] = (byte)tmp[k + 2];
}
dst += offset;
}
}
}
}
}