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

ProcessFilter() protected method

Process the filter on the specified image.
protected ProcessFilter ( UnmanagedImage sourceData, UnmanagedImage destinationData ) : void
sourceData UnmanagedImage Source image data.
destinationData UnmanagedImage Destination image data.
return void
        protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            // get source and destination images size
            int srcWidth = sourceData.Width;
            int srcHeight = sourceData.Height;
            int dstWidth = destinationData.Width;
            int dstHeight = destinationData.Height;

            int pixelSize = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
            int srcStride = sourceData.Stride;
            int dstStride = destinationData.Stride;
            int offset = dstStride - dstWidth * pixelSize;

            // calculate tranformation matrix
            List<IntPoint> dstRect = new List<IntPoint>();
            dstRect.Add(new IntPoint(0, 0));
            dstRect.Add(new IntPoint(dstWidth - 1, 0));
            dstRect.Add(new IntPoint(dstWidth - 1, dstHeight - 1));
            dstRect.Add(new IntPoint(0, dstHeight - 1));

            // calculate tranformation matrix
            double[,] matrix = QuadTransformationCalcs.MapQuadToQuad(dstRect, sourceQuadrilateral);

            // do the job
            byte* ptr = (byte*)destinationData.ImageData.ToPointer();
            byte* baseSrc = (byte*)sourceData.ImageData.ToPointer();

            if (!useInterpolation)
            {
                byte* p;

                // for each row
                for (int y = 0; y < dstHeight; y++)
                {
                    // for each pixel
                    for (int x = 0; x < dstWidth; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            // get pointer to the pixel in the source image
                            p = baseSrc + (int)srcY * srcStride + (int)srcX * pixelSize;
                            // copy pixel's values
                            for (int i = 0; i < pixelSize; i++, ptr++, p++)
                            {
                                *ptr = *p;
                            }
                        }
                        else
                        {
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
            else
            {
                int srcWidthM1 = srcWidth - 1;
                int srcHeightM1 = srcHeight - 1;

                // coordinates of source points
                double dx1, dy1, dx2, dy2;
                int sx1, sy1, sx2, sy2;

                // temporary pointers
                byte* p1, p2, p3, p4;

                // for each row
                for (int y = 0; y < dstHeight; y++)
                {
                    // for each pixel
                    for (int x = 0; x < dstWidth; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            sx1 = (int)srcX;
                            sx2 = (sx1 == srcWidthM1) ? sx1 : sx1 + 1;
                            dx1 = srcX - sx1;
                            dx2 = 1.0 - dx1;

                            sy1 = (int)srcY;
                            sy2 = (sy1 == srcHeightM1) ? sy1 : sy1 + 1;
                            dy1 = srcY - sy1;
                            dy2 = 1.0 - dy1;

                            // get four points
                            p1 = p2 = baseSrc + sy1 * srcStride;
                            p1 += sx1 * pixelSize;
                            p2 += sx2 * pixelSize;

                            p3 = p4 = baseSrc + sy2 * srcStride;
                            p3 += sx1 * pixelSize;
                            p4 += sx2 * pixelSize;

                            // interpolate using 4 points
                            for (int i = 0; i < pixelSize; i++, ptr++, p1++, p2++, p3++, p4++)
                            {
                                *ptr = (byte)(
                                    dy2 * (dx2 * (*p1) + dx1 * (*p2)) +
                                    dy1 * (dx2 * (*p3) + dx1 * (*p4)));
                            }
                        }
                        else
                        {
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
        }
    }