private unsafe void ProcessImage( UnmanagedImage image, Rectangle rect, byte* mask, int maskLineSize )
{
int pixelSize = Bitmap.GetPixelFormatSize( image.PixelFormat ) / 8;
int startY = rect.Top;
int stopY = startY + rect.Height;
int startX = rect.Left;
int stopX = startX + rect.Width;
int stride = image.Stride;
int maskOffset = maskLineSize - rect.Width;
// allign mask to the first pixel
mask += maskLineSize * startY + startX;
if ( ( pixelSize <= 4 ) && ( pixelSize != 2 ) )
{
// 8 bits per channel
byte* imagePtr = (byte*) image.ImageData.ToPointer( ) +
stride * startY + pixelSize * startX;
int offset = stride - rect.Width * pixelSize;
#region 8 bit cases
switch ( pixelSize )
{
case 1:
// 8 bpp grayscale
for ( int y = startY; y < stopY; y++ )
{
for ( int x = startX; x < stopX; x++, imagePtr++, mask++ )
{
if ( *mask == 0 )
{
*imagePtr = 0;
}
}
imagePtr += offset;
mask += maskOffset;
}
break;
case 3:
// 24 bpp color
for ( int y = startY; y < stopY; y++ )
{
for ( int x = startX; x < stopX; x++, imagePtr += 3, mask++ )
{
if ( *mask == 0 )
{
imagePtr[RGB.R] = 0;
imagePtr[RGB.G] = 0;
imagePtr[RGB.B] = 0;
}
}
imagePtr += offset;
mask += maskOffset;
}
break;
case 4:
// 32 bpp color
for ( int y = startY; y < stopY; y++ )
{
for ( int x = startX; x < stopX; x++, imagePtr += 4, mask++ )
{
if ( *mask == 0 )
{
imagePtr[RGB.R] = 0;
imagePtr[RGB.G] = 0;
imagePtr[RGB.B] = 0;
imagePtr[RGB.A] = 0;
}
}
imagePtr += offset;
mask += maskOffset;
}
break;
}
#endregion
}
else
{
// 16 bits per channel
byte* imagePtrBase = (byte*) image.ImageData.ToPointer( ) +
stride * startY + pixelSize * startX;
#region 16 bit cases
switch ( pixelSize )
{
case 2:
// 16 bpp grayscale
for ( int y = startY; y < stopY; y++ )
{
ushort* imagePtr = (ushort*) imagePtrBase;
for ( int x = startX; x < stopX; x++, imagePtr++, mask++ )
{
if ( *mask == 0 )
{
*imagePtr = 0;
}
}
imagePtrBase += stride;
mask += maskOffset;
}
break;
case 6:
// 16 bpp grayscale
for ( int y = startY; y < stopY; y++ )
{
ushort* imagePtr = (ushort*) imagePtrBase;
for ( int x = startX; x < stopX; x++, imagePtr += 3, mask++ )
{
if ( *mask == 0 )
{
imagePtr[RGB.R] = 0;
imagePtr[RGB.G] = 0;
imagePtr[RGB.B] = 0;
}
}
imagePtrBase += stride;
mask += maskOffset;
}
break;
case 8:
// 16 bpp grayscale
for ( int y = startY; y < stopY; y++ )
{
ushort* imagePtr = (ushort*) imagePtrBase;
for ( int x = startX; x < stopX; x++, imagePtr += 4, mask++ )
{
if ( *mask == 0 )
{
imagePtr[RGB.R] = 0;
imagePtr[RGB.G] = 0;
imagePtr[RGB.B] = 0;
imagePtr[RGB.A] = 0;
}
}
imagePtrBase += stride;
mask += maskOffset;
}
break;
}
#endregion
}
}
}