protected override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
{
// check image format
if (
(sourceData.PixelFormat != PixelFormat.Format8bppIndexed) &&
(sourceData.PixelFormat != PixelFormat.Format16bppGrayScale)
)
{
throw new UnsupportedImageFormatException("Only grayscale images are supported.");
}
// get source image size
int width = sourceData.Width;
int height = sourceData.Height;
int srcPixelSize = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
int dstPixelSize = System.Drawing.Image.GetPixelFormatSize(destinationData.PixelFormat) / 8;
int srcOffset = sourceData.Stride - width * srcPixelSize;
int dstOffset = destinationData.Stride - width * dstPixelSize;
// check image size
if ((!Accord.Math.Tools.IsPowerOf2(width)) || (!Accord.Math.Tools.IsPowerOf2(height)))
{
throw new InvalidImagePropertiesException("Image width and height should be power of 2.");
}
// create new complex image
double[,] data = new double[width, height];
if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed)
{
// do the job
unsafe
{
byte* src = (byte*)sourceData.ImageData.ToPointer();
// for each line
for (int y = 0; y < height; y++)
{
// for each pixel
for (int x = 0; x < width; x++, src++)
{
data[y, x] = Vector.Scale(*src, (byte)0, (byte)255, -1.0, 1.0);
}
src += srcOffset;
}
}
}
else
{
// do the job
unsafe
{
ushort* src = (ushort*)sourceData.ImageData.ToPointer();
// for each line
for (int y = 0; y < height; y++)
{
// for each pixel
for (int x = 0; x < width; x++, src++)
{
data[y, x] = Vector.Scale(*src, 0, 65535, -1.0, 1.0);
}
src += srcOffset;
}
}
}
// Apply the transform
if (backward)
{
wavelet.Backward(data);
}
else
{
wavelet.Forward(data);
}
if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed)
{
unsafe
{
byte* dst = (byte*)destinationData.ImageData.ToPointer();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, dst++)
{
*dst = (byte)Vector.Scale(data[y, x], -1, 1, 0, 255);
}
dst += dstOffset;
}
}
}
else
{
unsafe
{
ushort* dst = (ushort*)destinationData.ImageData.ToPointer();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, dst++)
{
*dst = (ushort)Vector.Scale(data[y, x], -1, 1, 0, 65535);
}
dst += dstOffset;
}
}
}
}
}