Accord.Imaging.Filters.RotateNearestNeighbor.ProcessFilter8bpc C# (CSharp) Method

ProcessFilter8bpc() private method

private ProcessFilter8bpc ( UnmanagedImage sourceData, UnmanagedImage destinationData ) : void
sourceData Accord.Imaging.UnmanagedImage
destinationData Accord.Imaging.UnmanagedImage
return void
        private unsafe void ProcessFilter8bpc(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            // get source image size
            int width = sourceData.Width;
            int height = sourceData.Height;
            double oldXradius = (double)(width - 1) / 2;
            double oldYradius = (double)(height - 1) / 2;

            // get destination image size
            int newWidth = destinationData.Width;
            int newHeight = destinationData.Height;
            double newXradius = (double)(newWidth - 1) / 2;
            double newYradius = (double)(newHeight - 1) / 2;

            // angle's sine and cosine
            double angleRad = -angle * Math.PI / 180;
            double angleCos = Math.Cos(angleRad);
            double angleSin = Math.Sin(angleRad);

            int srcStride = sourceData.Stride;
            int dstOffset = destinationData.Stride -
                ((destinationData.PixelFormat == PixelFormat.Format8bppIndexed) ? newWidth : newWidth * 3);

            // fill values
            byte fillA = fillColor.A;
            byte fillR = fillColor.R;
            byte fillG = fillColor.G;
            byte fillB = fillColor.B;

            // do the job
            byte* src = (byte*)sourceData.ImageData.ToPointer();
            byte* dst = (byte*)destinationData.ImageData.ToPointer();

            // destination pixel's coordinate relative to image center
            double cx, cy;
            // source pixel's coordinates
            int ox, oy;
            // temporary pointer
            byte* p;

            // check pixel format
            if (destinationData.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                // grayscale
                cy = -newYradius;
                for (int y = 0; y < newHeight; y++)
                {
                    cx = -newXradius;
                    for (int x = 0; x < newWidth; x++, dst++)
                    {
                        // coordinate of the nearest point
                        ox = (int)(angleCos * cx + angleSin * cy + oldXradius);
                        oy = (int)(-angleSin * cx + angleCos * cy + oldYradius);

                        // validate source pixel's coordinates
                        if ((ox < 0) || (oy < 0) || (ox >= width) || (oy >= height))
                        {
                            // fill destination image with filler
                            *dst = fillG;
                        }
                        else
                        {
                            // fill destination image with pixel from source image
                            *dst = src[oy * srcStride + ox];
                        }
                        cx++;
                    }
                    cy++;
                    dst += dstOffset;
                }
            }
            else if (destinationData.PixelFormat == PixelFormat.Format24bppRgb
                  || destinationData.PixelFormat == PixelFormat.Format32bppRgb)
            {
                // RGB
                cy = -newYradius;
                for (int y = 0; y < newHeight; y++)
                {
                    cx = -newXradius;
                    for (int x = 0; x < newWidth; x++, dst += 3)
                    {
                        // coordinate of the nearest point
                        ox = (int)(angleCos * cx + angleSin * cy + oldXradius);
                        oy = (int)(-angleSin * cx + angleCos * cy + oldYradius);

                        // validate source pixel's coordinates
                        if ((ox < 0) || (oy < 0) || (ox >= width) || (oy >= height))
                        {
                            // fill destination image with filler
                            dst[RGB.R] = fillR;
                            dst[RGB.G] = fillG;
                            dst[RGB.B] = fillB;
                        }
                        else
                        {
                            // fill destination image with pixel from source image
                            p = src + oy * srcStride + ox * 3;

                            dst[RGB.R] = p[RGB.R];
                            dst[RGB.G] = p[RGB.G];
                            dst[RGB.B] = p[RGB.B];
                        }
                        cx++;
                    }
                    cy++;
                    dst += dstOffset;
                }
            }
            else if (destinationData.PixelFormat == PixelFormat.Format32bppArgb)
            {
                // ARGB
                cy = -newYradius;
                for (int y = 0; y < newHeight; y++)
                {
                    cx = -newXradius;
                    for (int x = 0; x < newWidth; x++, dst += 3)
                    {
                        // coordinate of the nearest point
                        ox = (int)(angleCos * cx + angleSin * cy + oldXradius);
                        oy = (int)(-angleSin * cx + angleCos * cy + oldYradius);

                        // validate source pixel's coordinates
                        if ((ox < 0) || (oy < 0) || (ox >= width) || (oy >= height))
                        {
                            // fill destination image with filler
                            dst[RGB.A] = fillA;
                            dst[RGB.R] = fillR;
                            dst[RGB.G] = fillG;
                            dst[RGB.B] = fillB;
                        }
                        else
                        {
                            // fill destination image with pixel from source image
                            p = src + oy * srcStride + ox * 3;

                            dst[RGB.A] = p[RGB.A];
                            dst[RGB.R] = p[RGB.R];
                            dst[RGB.G] = p[RGB.G];
                            dst[RGB.B] = p[RGB.B];
                        }
                        cx++;
                    }
                    cy++;
                    dst += dstOffset;
                }
            }
            else
            {
                throw new UnsupportedImageFormatException();
            }
        }