private unsafe void ProcessFilter16bpc( UnmanagedImage image )
{
int pixelSize = Image.GetPixelFormatSize( image.PixelFormat ) / 8;
bool is64bpp = ( pixelSize == 8 );
// pad fill colours to 16-bits
ushort fillRed = (ushort) ( this.fillRed << 8 );
ushort fillGreen = (ushort) ( this.fillGreen << 8 );
ushort fillBlue = (ushort) ( this.fillBlue << 8 );
ushort fillAlpha = (ushort) ( this.fillAlpha << 8 );
// get image width and height
int width = image.Width;
int height = image.Height;
int stride = image.Stride;
int movePointX = movePoint.X;
int movePointY = movePoint.Y;
// intersection rectangle
Rectangle intersect = Rectangle.Intersect(
new Rectangle( 0, 0, width, height ),
new Rectangle( movePointX, movePointY, width, height ) );
// start, stop and step for X and Y
int yStart = 0;
int yStop = height;
int yStep = 1;
int xStart = 0;
int xStop = width;
int xStep = 1;
if ( movePointY > 0 )
{
yStart = height - 1;
yStop = -1;
yStep = -1;
}
if ( movePointX > 0 )
{
xStart = width - 1;
xStop = -1;
xStep = -1;
}
// do the job
byte* src = (byte*) image.ImageData.ToPointer( );
ushort* pixel, moved;
if ( image.PixelFormat == PixelFormat.Format16bppGrayScale )
{
// grayscale image
for ( int y = yStart; y != yStop; y += yStep )
{
for ( int x = xStart; x != xStop; x += xStep )
{
// current pixel
pixel = (ushort*) ( src + y * stride + x * 2 );
if ( intersect.Contains( x, y ) )
{
moved = (ushort*) ( src + ( y - movePointY ) * stride + ( x - movePointX ) * 2 );
*pixel = *moved;
}
else
{
*pixel = fillGray;
}
}
}
}
else
{
// color image
for ( int y = yStart; y != yStop; y += yStep )
{
for ( int x = xStart; x != xStop; x += xStep )
{
// current pixel
pixel = (ushort*) ( src + y * stride + x * pixelSize );
if ( intersect.Contains( x, y ) )
{
moved = (ushort*) ( src + ( y - movePointY ) * stride + ( x - movePointX ) * pixelSize );
pixel[RGB.R] = moved[RGB.R];
pixel[RGB.G] = moved[RGB.G];
pixel[RGB.B] = moved[RGB.B];
if ( is64bpp )
{
pixel[RGB.A] = moved[RGB.A];
}
}
else
{
pixel[RGB.R] = fillRed;
pixel[RGB.G] = fillGreen;
pixel[RGB.B] = fillBlue;
if ( is64bpp )
{
pixel[RGB.A] = fillAlpha;
}
}
}
}
}
}
}