private static Complex[,] FromBitmapData(BitmapData _BitmapData)
{
if (_BitmapData.PixelFormat != PixelFormat.Format8bppIndexed)
{
throw new Exception("Source can be grayscale (8bpp indexed) only.");
}
int width = _BitmapData.Width;
int height = _BitmapData.Height;
int offset = _BitmapData.Stride - width;
if ((!Utils.IsPowerOf2(width)) || (!Utils.IsPowerOf2(height)))
{
throw new Exception("Image width and height should be power of 2.");
}
Complex[,] data = new Complex[width, height];
unsafe
{
byte* src = (byte*)_BitmapData.Scan0.ToPointer();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, src++)
{
data[y, x] = new Complex((float)*src / 255,
data[y, x].Imaginary);
}
src += offset;
}
}
return data;
}
Why is the value pointed by *src
is divided by 255?
What is Stride
?
For purposes like alignment, etc. sometimes row of pixels in a bitmap is longer than width - and it’s length is called stride. So, you could have width = 3 and stride = 4, and row of data would look like this:
Row: [Pixel][Pixel][Pixel][Unused]
What does offset
represent?
It’s a difference between stride and width, i.e. when you have read all real pixels in a row, how much unused ones you need to skip in order to get to next row.
Why is src
incremented by 1 in the inner loop, and, again incremented by offset
in the outer loop?
Inner loop reads pixels of the row, so src
is incremented by 1 to get to next pixel in every iteration. But after you read them all, you need to skip offset
of unused data to get to next row.
Why is the value pointed by *src
is divided by 255
?
Complex type has floating point components, and pixels in 8bpp bitmaps are represented by bytes, so they have values from 0–255
. Dividing by 255
converts them to floating point numbers in range 0.0–1.0
.
Why is data[x,y].Imaginary
passed as a parameter?
For some reason, this function stores bitmap data in complex type, and complex type has real and imaginary components, so assigning
data[y, x] = new Complex(something, data[y,x].Imaginary);
means: set real component of data[y,x]
to something and leave imaginary component as it is.