Accord.Imaging.Filters.OilPainting.ProcessFilter C# (CSharp) Method

ProcessFilter() protected method

Process the filter on the specified image.
protected ProcessFilter ( UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect ) : void
sourceData UnmanagedImage Source image data.
destinationData UnmanagedImage Destination image data.
rect System.Drawing.Rectangle Image rectangle for processing by the filter.
return void
        protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData, Rectangle rect)
        {
            int pixelSize = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;

            // processing start and stop X,Y positions
            int startX = rect.Left;
            int startY = rect.Top;
            int stopX = startX + rect.Width;
            int stopY = startY + rect.Height;

            int srcStride = sourceData.Stride;
            int dstStride = destinationData.Stride;
            int srcOffset = srcStride - rect.Width * pixelSize;
            int dstOffset = srcStride - rect.Width * pixelSize;

            // loop and array indexes
            int i, j, t;
            // brush radius
            int radius = brushSize >> 1;

            // intensity values
            byte intensity, maxIntensity;
            int[] intensities = new int[256];

            byte* src = (byte*)sourceData.ImageData.ToPointer();
            byte* dst = (byte*)destinationData.ImageData.ToPointer();
            byte* p;

            // allign pointers to the first pixel to process
            src += (startY * srcStride + startX * pixelSize);
            dst += (startY * dstStride + startX * pixelSize);

            if (destinationData.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                // Grayscale image

                // for each line
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++, src++, dst++)
                    {
                        // clear arrays
                        Array.Clear(intensities, 0, 256);

                        // for each kernel row
                        for (i = -radius; i <= radius; i++)
                        {
                            t = y + i;

                            // skip row
                            if (t < startY)
                                continue;
                            // break
                            if (t >= stopY)
                                break;

                            // for each kernel column
                            for (j = -radius; j <= radius; j++)
                            {
                                t = x + j;

                                // skip column
                                if (t < startX)
                                    continue;

                                if (t < stopX)
                                {
                                    intensity = src[i * srcStride + j];
                                    intensities[intensity]++;
                                }
                            }
                        }

                        // get most frequent intesity
                        maxIntensity = 0;
                        j = 0;

                        for (i = 0; i < 256; i++)
                        {
                            if (intensities[i] > j)
                            {
                                maxIntensity = (byte)i;
                                j = intensities[i];
                            }
                        }

                        // set destination pixel
                        *dst = maxIntensity;
                    }
                    src += srcOffset;
                    dst += dstOffset;
                }
            }
            else
            {
                // RGB image
                int[] red = new int[256];
                int[] green = new int[256];
                int[] blue = new int[256];

                // for each line
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++, src += pixelSize, dst += pixelSize)
                    {
                        // clear arrays
                        Array.Clear(intensities, 0, 256);
                        Array.Clear(red, 0, 256);
                        Array.Clear(green, 0, 256);
                        Array.Clear(blue, 0, 256);

                        // for each kernel row
                        for (i = -radius; i <= radius; i++)
                        {
                            t = y + i;

                            // skip row
                            if (t < startY)
                                continue;
                            // break
                            if (t >= stopY)
                                break;

                            // for each kernel column
                            for (j = -radius; j <= radius; j++)
                            {
                                t = x + j;

                                // skip column
                                if (t < startX)
                                    continue;

                                if (t < stopX)
                                {
                                    p = &src[i * srcStride + j * pixelSize];

                                    // grayscale value using BT709
                                    intensity = (byte)(0.2125 * p[RGB.R] + 0.7154 * p[RGB.G] + 0.0721 * p[RGB.B]);

                                    //
                                    intensities[intensity]++;
                                    // red
                                    red[intensity] += p[RGB.R];
                                    // green
                                    green[intensity] += p[RGB.G];
                                    // blue
                                    blue[intensity] += p[RGB.B];
                                }
                            }
                        }

                        // get most frequent intesity
                        maxIntensity = 0;
                        j = 0;

                        for (i = 0; i < 256; i++)
                        {
                            if (intensities[i] > j)
                            {
                                maxIntensity = (byte)i;
                                j = intensities[i];
                            }
                        }

                        // set destination pixel
                        dst[RGB.R] = (byte)(red[maxIntensity] / intensities[maxIntensity]);
                        dst[RGB.G] = (byte)(green[maxIntensity] / intensities[maxIntensity]);
                        dst[RGB.B] = (byte)(blue[maxIntensity] / intensities[maxIntensity]);
                    }
                    src += srcOffset;
                    dst += dstOffset;
                }
            }
        }
    }