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

ProcessFilter() protected method

Process the filter on the specified image.
protected ProcessFilter ( UnmanagedImage image, Rectangle rect ) : void
image UnmanagedImage Source image data.
rect System.Drawing.Rectangle Image rectangle for processing by the filter.
return void
        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;
                    }
                }
            }
        }
    }