ImageProcessor.Processor.Convolve C# (CSharp) Method

Convolve() public method

public Convolve ( short weights ) : Image
weights short
return Image
        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;
        }