AForge.Imaging.Filters.YCbCrReplaceChannel.ProcessFilter C# (CSharp) Method

ProcessFilter() protected method

Process the filter on the specified image.
Channel image size does not match source /// image size.
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.GetPixelFormatSize( image.PixelFormat ) / 8;

            int width   = image.Width;
            int height  = image.Height;
            int startX  = rect.Left;
            int startY  = rect.Top;
            int stopX   = startX + rect.Width;
            int stopY   = startY + rect.Height;
            int offset  = image.Stride - rect.Width * pixelSize;

            BitmapData chData = null;
            // pointer to channel's data
            byte* ch;
            // channel's image stride
            int chStride = 0;

            // check channel's image type
            if ( channelImage != null )
            {
                // check channel's image dimension
                if ( ( width != channelImage.Width ) || ( height != channelImage.Height ) )
                    throw new InvalidImagePropertiesException( "Channel image size does not match source image size." );

                // lock channel image
                chData = channelImage.LockBits(
                    new Rectangle( 0, 0, width, height ),
                    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed );

                ch = (byte*) chData.Scan0.ToPointer( );
                chStride = chData.Stride;
            }
            else
            {
                // check channel's image dimension
                if ( ( width != unmanagedChannelImage.Width ) || ( height != unmanagedChannelImage.Height ) )
                    throw new InvalidImagePropertiesException( "Channel image size does not match source image size." );

                ch = (byte*) unmanagedChannelImage.ImageData;
                chStride = unmanagedChannelImage.Stride;
            }

            int     offsetCh = chStride - rect.Width;
            RGB     rgb = new RGB( );
            YCbCr   ycbcr = new YCbCr( );

            // do the job
            byte* dst = (byte*) image.ImageData.ToPointer( );

            // allign pointer to the first pixel to process
            dst += ( startY * image.Stride + startX * pixelSize );
            ch += ( startY * chStride + startX );

            // for each line
            for ( int y = startY; y < stopY; y++ )
            {
                // for each pixel
                for ( int x = startX; x < stopX; x++, dst += pixelSize, ch++ )
                {
                    rgb.Red     = dst[RGB.R];
                    rgb.Green   = dst[RGB.G];
                    rgb.Blue    = dst[RGB.B];

                    // convert to YCbCr
                    AForge.Imaging.YCbCr.FromRGB( rgb, ycbcr );

                    switch ( channel )
                    {
                        case YCbCr.YIndex:
                            ycbcr.Y = (float) *ch / 255;
                            break;

                        case YCbCr.CbIndex:
                            ycbcr.Cb = (float) *ch / 255 - 0.5f;
                            break;

                        case YCbCr.CrIndex:
                            ycbcr.Cr = (float) *ch / 255 - 0.5f;
                            break;
                    }

                    // convert back to RGB
                    AForge.Imaging.YCbCr.ToRGB( ycbcr, rgb );

                    dst[RGB.R] = rgb.Red;
                    dst[RGB.G] = rgb.Green;
                    dst[RGB.B] = rgb.Blue;
                }
                dst += offset;
                ch  += offsetCh;
            }

            if ( chData != null )
            {
                // unlock
                channelImage.UnlockBits( chData );
            }
        }
    }