AForge.Imaging.Filters.BayerFilterOptimized.ApplyGRBG C# (CSharp) Method

ApplyGRBG() private method

private ApplyGRBG ( UnmanagedImage sourceData, UnmanagedImage destinationData ) : void
sourceData UnmanagedImage
destinationData UnmanagedImage
return void
        private unsafe void ApplyGRBG( 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

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

            src++;
            dst += 3;

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

                src++;
                dst += 3;

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

                src++;
                dst += 3;
            }

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


            // 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 )
            {
                // . G R
                // . B G
                // . G R
                dst[RGB.R] = (byte) ( ( src[srcMStrideP1] + src[srcStrideP1] ) >> 1 );
                dst[RGB.G] = (byte) ( ( src[srcMStride] + src[srcStride] + src[1] ) / 3 );
                dst[RGB.B] = *src;

                dst += dstStride;
                src += srcStride;

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

                dst -= dstStride;
                src -= srcStride;

                src++;
                dst += 3;

                for ( int x = 1; x < widthM1; x += 2 )
                {
                    // G R G
                    // B G B
                    // G R G
                    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 pixel )
                    // B G B
                    // G R G
                    // B G B
                    dst += dstStride;
                    src += srcStride;

                    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 x+1 pixel )
                    // G B G
                    // R G R
                    // G B G
                    dst += 3;
                    src++;

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

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

                    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;

                    dst += 3;
                    src++;
                }

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

                src += srcStride;
                dst += dstStride;

                // ( y+1 pixel )
                // 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 );


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

            // --- process the first line

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

            src++;
            dst += 3;

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

                src++;
                dst += 3;

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

                src++;
                dst += 3;
            }

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