private static 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
}
}
}