protected override unsafe void ProcessFilter(UnmanagedImage image, Rectangle rect)
{
int pixelSize = Image.GetPixelFormatSize(image.PixelFormat) / 8;
int startX = rect.Left;
int startY = rect.Top;
int stopX = startX + rect.Width;
int stopY = startY + rect.Height;
int stride = image.Stride;
int offset = stride - rect.Width * pixelSize;
// levels linear correction filter is going to be used on STEP 2
LevelsLinear levelsLinear = new LevelsLinear();
// STEP 1 - search for min and max pixel values
byte* ptr = (byte*)image.ImageData.ToPointer();
// check image format
if (image.PixelFormat == PixelFormat.Format8bppIndexed)
{
// allign pointer to the first pixel to process
ptr += (startY * stride + startX);
byte min = 255;
byte max = 0;
for (int y = startY; y < stopY; y++)
{
for (int x = startX; x < stopX; x++, ptr++)
{
byte value = *ptr;
if (value < min)
min = value;
if (value > max)
max = value;
}
ptr += offset;
}
levelsLinear.InGray = new IntRange(min, max);
}
else
{
// allign pointer to the first pixel to process
ptr += (startY * stride + startX * pixelSize);
byte minR = 255, minG = 255, minB = 255;
byte maxR = 0, maxG = 0, maxB = 0;
for (int y = startY; y < stopY; y++)
{
for (int x = startX; x < stopX; x++, ptr += pixelSize)
{
// red
byte value = ptr[RGB.R];
if (value < minR)
minR = value;
if (value > maxR)
maxR = value;
// green
value = ptr[RGB.G];
if (value < minG)
minG = value;
if (value > maxG)
maxG = value;
// blue
value = ptr[RGB.B];
if (value < minB)
minB = value;
if (value > maxB)
maxB = value;
}
ptr += offset;
}
levelsLinear.InRed = new IntRange(minR, maxR);
levelsLinear.InGreen = new IntRange(minG, maxG);
levelsLinear.InBlue = new IntRange(minB, maxB);
}
// STEP 2 - run levels linear correction
levelsLinear.ApplyInPlace(image, rect);
}
}