Accord.Imaging.Filters.BilateralSmoothing.ProcessWithoutChecksParallel C# (CSharp) Method

ProcessWithoutChecksParallel() private method

private ProcessWithoutChecksParallel ( UnmanagedImage source, UnmanagedImage destination, Rectangle rect ) : void
source UnmanagedImage
destination UnmanagedImage
rect System.Drawing.Rectangle
return void
        private unsafe void ProcessWithoutChecksParallel(UnmanagedImage source, UnmanagedImage destination, Rectangle rect)
        {
            int startX = rect.Left;
            int startY = rect.Top;
            int stopX = rect.Right;
            int stopY = rect.Bottom;

            int pixelSize = System.Drawing.Image.GetPixelFormatSize(source.PixelFormat) / 8;
            int kernelHalf = kernelSize / 2;
            int bytesInKernelRow = kernelSize * pixelSize;

            int srcStride = source.Stride;
            int dstStride = destination.Stride;


            // offset of the first kernel's pixel
            int srcKernelFistPixelOffset = kernelHalf * (srcStride + pixelSize);

            // offset to move to the next kernel's pixel after processing one kernel's row
            int srcKernelOffset = srcStride - bytesInKernelRow;

            byte* srcBase = (byte*)source.ImageData.ToPointer();
            byte* dstBase = (byte*)destination.ImageData.ToPointer();

            // align pointers to the left most pixel in the first row
            srcBase += startX * pixelSize;
            dstBase += startX * pixelSize;

            if (pixelSize > 1)
            {
                Parallel.For(startY, stopY, delegate(int y)
                {
                    byte* src = srcBase + y * srcStride;
                    byte* dst = dstBase + y * dstStride;

                    byte srcR, srcG, srcB;
                    byte srcR0, srcG0, srcB0;
                    byte* srcPixel;

                    int tx, ty;

                    double sCoefR, sCoefG, sCoefB, sMembR, sMembG, sMembB, coefR, coefG, coefB;

                    for (int x = startX; x < stopX; x++, src += pixelSize, dst += pixelSize)
                    {
                        // lower right corner - to start processing from that point
                        srcPixel = src + srcKernelFistPixelOffset;

                        sCoefR = 0;
                        sCoefG = 0;
                        sCoefB = 0;
                        sMembR = 0;
                        sMembG = 0;
                        sMembB = 0;

                        srcR0 = src[RGB.R];
                        srcG0 = src[RGB.G];
                        srcB0 = src[RGB.B];

                        // move from lower right to upper left corner
                        ty = kernelSize;
                        while (ty != 0)
                        {
                            ty--;

                            tx = kernelSize;
                            while (tx != 0)
                            {
                                tx--;

                                srcR = srcPixel[RGB.R];
                                srcG = srcPixel[RGB.G];
                                srcB = srcPixel[RGB.B];

                                coefR = spatialFunc[tx, ty] * colorFunc[srcR, srcR0];
                                coefG = spatialFunc[tx, ty] * colorFunc[srcG, srcG0];
                                coefB = spatialFunc[tx, ty] * colorFunc[srcB, srcB0];

                                sCoefR += coefR;
                                sCoefG += coefG;
                                sCoefB += coefB;

                                sMembR += coefR * srcR;
                                sMembG += coefG * srcG;
                                sMembB += coefB * srcB;

                                srcPixel -= pixelSize;
                            }

                            srcPixel -= srcKernelOffset;
                        }

                        dst[RGB.R] = (byte)(sMembR / sCoefR);
                        dst[RGB.G] = (byte)(sMembG / sCoefG);
                        dst[RGB.B] = (byte)(sMembB / sCoefB);
                    }
                });
            }
            else
            {
                // 8bpp grayscale images
                Parallel.For(startY, stopY, delegate(int y)
                {
                    byte* src = srcBase + y * srcStride;
                    byte* dst = dstBase + y * dstStride;

                    byte srcC;
                    byte srcC0;
                    byte* srcPixel;
                    double sCoefC, sMembC, coefC;

                    int tx, ty;

                    for (int x = startX; x < stopX; x++, src++, dst++)
                    {
                        // lower right corner - to start processing from that point
                        srcPixel = src + srcKernelFistPixelOffset;

                        sCoefC = 0;
                        sMembC = 0;

                        srcC0 = *src;

                        // move from lower right to upper left corner
                        ty = kernelSize;
                        while (ty != 0)
                        {
                            ty--;

                            tx = kernelSize;
                            while (tx != 0)
                            {
                                tx--;

                                srcC = *(srcPixel);
                                coefC = spatialFunc[tx, ty] * colorFunc[srcC, srcC0];

                                sCoefC += coefC;
                                sMembC += coefC * srcC;

                                srcPixel -= pixelSize;
                            }

                            srcPixel -= srcKernelOffset;
                        }

                        *dst = (byte)(sMembC / sCoefC);
                    }
                });
            }
        }