Accord.Imaging.Filters.BayerFilterOptimized.ApplyBGGR C# (CSharp) Method

ApplyBGGR() private static method

private static ApplyBGGR ( UnmanagedImage sourceData, UnmanagedImage destinationData ) : void
sourceData UnmanagedImage
destinationData UnmanagedImage
return void
        private static unsafe void ApplyBGGR(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            int width = sourceData.Width;
            int height = sourceData.Height;

            int widthM1 = width - 1;
            int heightM1 = height - 1;

            int srcStride = sourceData.Stride;
            int dstStride = destinationData.Stride;

            int srcStrideP1 = srcStride + 1;
            int srcStrideM1 = srcStride - 1;
            int srcMStride = -srcStride;
            int srcMStrideP1 = srcMStride + 1;
            int srcMStrideM1 = srcMStride - 1;

            int srcOffset = srcStride - width;
            int dstOffset = dstStride - width * 3;

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

            // --- process the first line

            // . . .
            // . B G 
            // . G R
            dst[RGB.R] = src[srcStrideP1];
            dst[RGB.G] = (byte)((src[1] + src[srcStride]) >> 1);
            dst[RGB.B] = *src;

            src++;
            dst += 3;

            for (int x = 1; x < widthM1; x += 2)
            {
                // . . .
                // B G B 
                // G R G
                dst[RGB.R] = src[srcStride];
                dst[RGB.G] = (byte)((*src + src[srcStrideM1] + src[srcStrideP1]) / 3);
                dst[RGB.B] = (byte)((src[-1] + src[1]) >> 1);

                src++;
                dst += 3;

                // . . .
                // G B G
                // R G R
                dst[RGB.R] = (byte)((src[srcStrideM1] + src[srcStrideP1]) >> 1);
                dst[RGB.G] = (byte)((src[-1] + src[srcStride] + src[1]) / 3);
                dst[RGB.B] = *src;

                src++;
                dst += 3;
            }

            // . . .
            // B G . 
            // G R . 
            dst[RGB.R] = src[srcStride];
            dst[RGB.G] = (byte)((*src + src[srcStrideM1]) >> 1);
            dst[RGB.B] = src[-1];


            // allign to the next line
            src += srcOffset + 1;
            dst += dstOffset + 3;

            // --- process all lines except the first one and the last one
            for (int y = 1; y < heightM1; y += 2)
            {
                // . B G 
                // . G R
                // . B G
                dst[RGB.R] = src[1];
                dst[RGB.G] = (byte)((src[srcMStrideP1] + src[srcStrideP1] + *src) / 3);
                dst[RGB.B] = (byte)((src[srcMStride] + src[srcStride]) >> 1);

                dst += dstStride;
                src += srcStride;

                // ( y+1 pixel )
                // . G R
                // . B G
                // . G R
                dst[RGB.R] = (byte)((src[srcMStrideP1] + src[srcStrideP1]) >> 1);
                dst[RGB.G] = (byte)((src[1] + src[srcMStride] + src[srcStride]) / 3);
                dst[RGB.B] = *src;

                dst -= dstStride;
                src -= srcStride;

                src++;
                dst += 3;

                for (int x = 1; x < widthM1; x += 2)
                {
                    // B G B
                    // G R G
                    // B G B
                    dst[RGB.R] = *src;
                    dst[RGB.G] = (byte)((src[srcMStride] + src[srcStride] + src[-1] + src[1]) >> 2);
                    dst[RGB.B] = (byte)((src[srcMStrideM1] + src[srcMStrideP1] + src[srcStrideM1] + src[srcStrideP1]) >> 2);

                    // ( y+1 pixel )
                    // G R G
                    // B G B
                    // G R G
                    dst += dstStride;
                    src += srcStride;

                    dst[RGB.R] = (byte)((src[srcMStride] + src[srcStride]) >> 1);
                    dst[RGB.G] = (byte)((*src + src[srcMStrideM1] + src[srcMStrideP1] + src[srcStrideM1] + src[srcStrideP1]) / 5);
                    dst[RGB.B] = (byte)((src[-1] + src[1]) >> 1);

                    // ( y+1 x+1 pixel )
                    // R G R
                    // G B G
                    // R G R
                    dst += 3;
                    src++;

                    dst[RGB.R] = (byte)((src[srcMStrideM1] + src[srcMStrideP1] + src[srcStrideM1] + src[srcStrideP1]) >> 2);
                    dst[RGB.G] = (byte)((src[srcMStride] + src[srcStride] + src[-1] + src[1]) >> 2);
                    dst[RGB.B] = *src;

                    // ( x+1 pixel )
                    // G B G
                    // R G R
                    // G B G
                    dst -= dstStride;
                    src -= srcStride;

                    dst[RGB.R] = (byte)((src[-1] + src[1]) >> 1);
                    dst[RGB.G] = (byte)((src[srcMStrideM1] + src[srcMStrideP1] + src[srcStrideM1] + src[srcStrideP1] + *src) / 5);
                    dst[RGB.B] = (byte)((src[srcMStride] + src[srcStride]) >> 1);

                    dst += 3;
                    src++;
                }

                // B G .
                // G R .
                // B G .
                dst[RGB.R] = *src;
                dst[RGB.G] = (byte)((src[srcMStride] + src[srcStride] + src[-1]) / 3);
                dst[RGB.B] = (byte)((src[srcMStrideM1] + src[srcStrideM1]) >> 1);
                src += srcStride;
                dst += dstStride;

                // ( y+1 pixel )
                // G R .
                // B G .
                // G R .
                dst[RGB.R] = (byte)((src[srcMStride] + src[srcStride]) >> 1);
                dst[RGB.G] = (byte)((src[srcMStrideM1] + src[srcStrideM1] + *src) / 3);
                dst[RGB.B] = src[-1];

                // align to the next line
                src += srcOffset + 1;
                dst += dstOffset + 3;
            }

            // --- process the first line

            // . B G 
            // . G R 
            // . . .
            dst[RGB.R] = src[1];
            dst[RGB.G] = (byte)((src[srcMStrideP1] + *src) >> 1);
            dst[RGB.B] = src[srcMStride];

            src++;
            dst += 3;

            for (int x = 1; x < widthM1; x += 2)
            {
                // B G B 
                // G R G 
                // . . .
                dst[RGB.R] = *src;
                dst[RGB.G] = (byte)((src[-1] + src[1] + src[srcMStride]) / 3);
                dst[RGB.B] = (byte)((src[srcMStrideM1] + src[srcMStrideP1]) >> 1);

                src++;
                dst += 3;

                // G B G
                // R G R 
                // . . .
                dst[RGB.R] = (byte)((src[-1] + src[1]) >> 1);
                dst[RGB.G] = (byte)((*src + src[srcMStrideM1] + src[srcMStrideP1]) / 3);
                dst[RGB.B] = src[srcMStride];

                src++;
                dst += 3;
            }

            // B G . 
            // G R . 
            // . . .
            dst[RGB.R] = *src;
            dst[RGB.G] = (byte)((src[srcMStride] + src[-1]) >> 1);
            dst[RGB.B] = src[srcMStrideM1];
        }
        #endregion