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

ProcessFilter() protected method

Process the filter on the specified image.
Channel image was not specified. Channel image size does not match source /// image size. Channel image's format does not correspond to format of the source image. Can not replace alpha channel of none ARGB image. The /// exception is throw, when alpha channel is requested to be replaced in RGB image.
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)
        {
            if ((channelImage == null) && (unmanagedChannelImage == null))
                throw new InvalidOperationException("Channel image was not specified.");

            int pixelSize = Image.GetPixelFormatSize(image.PixelFormat) / 8;

            if ((channel == RGB.A) && (pixelSize != 4) && (pixelSize != 8))
                throw new InvalidImagePropertiesException("Can not replace alpha channel of none ARGB image.");

            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;
            PixelFormat chFormat = PixelFormat.Format16bppGrayScale;

            // 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, channelImage.PixelFormat);

                ch = (byte*)chData.Scan0.ToPointer();
                chStride = chData.Stride;
                chFormat = chData.PixelFormat;
            }
            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;
                chFormat = unmanagedChannelImage.PixelFormat;
            }

            if (pixelSize <= 4)
            {
                // check channel image's format
                if (chFormat != PixelFormat.Format8bppIndexed)
                    throw new InvalidImagePropertiesException("Channel image's format does not correspond to format of the source image.");

                int offsetCh = chStride - rect.Width;

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

                // allign pointers 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++)
                    {
                        dst[channel] = *ch;
                    }
                    dst += offset;
                    ch += offsetCh;
                }
            }
            else
            {
                // check channel image's format
                if (chFormat != PixelFormat.Format16bppGrayScale)
                    throw new InvalidImagePropertiesException("Channel image's format does not correspond to format of the source image.");

                int stride = image.Stride;

                // do the job
                byte* baseDst = (byte*)image.ImageData.ToPointer();
                // allign pointers for X coordinate
                baseDst += startX * pixelSize;
                ch += startX * 2;

                pixelSize /= 2;

                // for each line
                for (int y = startY; y < stopY; y++)
                {
                    ushort* dst = (ushort*)(baseDst + y * stride);
                    ushort* chPtr = (ushort*)(ch + y * chStride);

                    // for each pixel
                    for (int x = startX; x < stopX; x++, dst += pixelSize, chPtr++)
                    {
                        dst[channel] = *chPtr;
                    }
                }
            }

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