public unsafe Image Convolve(short [,] weights)
{
Bitmap source = new Bitmap(_image);
Bitmap destination = new Bitmap((Image)_image.Clone());
BitmapData srcData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadWrite, source.PixelFormat);
BitmapData destData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.ReadWrite, destination.PixelFormat);
byte bytesPerPixel = (byte)(1/8d*GetBitsPerPixel(srcData.PixelFormat));
int size = srcData.Stride * srcData.Height;
byte* srcScan0 = (byte*)srcData.Scan0.ToPointer();
byte* destScan0 = (byte*)destData.Scan0.ToPointer();
int startX = weights.GetLength(0);
int startY = weights.GetLength(1);
int middleX = (int)Math.Floor(startX/2f);
int middleY = (int)Math.Floor(startY/2f);
int normFactor = SumWeights(weights);
int [] value = new int[3];
for (int i = middleY; i < srcData.Height-middleY; ++i)
{
for (int j = middleX; j < srcData.Width-middleX; ++j)
{
byte* srcCurrPx = srcScan0 + i * srcData.Stride + j * bytesPerPixel;
byte* destCurrPx = destScan0 + i * destData.Stride + j * bytesPerPixel;
for (int q = 0; q < startY; ++q)
{
for (int z = 0; z < startX; ++z)
{
byte *data = srcCurrPx + srcData.Stride * (q - middleY) + bytesPerPixel * (z - middleX);
value[0] = value[0]+data[0] * weights[z, q];
value[1] = value[1]+data[1] * weights[z, q];
value[2] = value[2]+data[2] * weights[z, q];
}
}
if (normFactor != 0)
{
value[0] = value[0] / normFactor;
value[1] = value[1] / normFactor;
value[2] = value[2] / normFactor;
}
else
{
value[0] = value[0] + 128;
value[1] = value[1] + 128;
value[2] = value[2] + 128;
}
if (value[0] > 255) value[0] = 255;
if (value[1] > 255) value[1] = 255;
if (value[2] > 255) value[2] = 255;
if (value[0] < 0) value[0] = 0;
if (value[1] < 0) value[1] = 0;
if (value[2] < 0) value[2] = 0;
destCurrPx[0] = (byte)value[0];
destCurrPx[1] = (byte)value[1];
destCurrPx[2] = (byte)value[2];
value = new int[3];
}
}
source.UnlockBits(srcData);
destination.UnlockBits(destData);
return destination;
}