Reputation: 11151
In C, I can define a pointer to an array like this:
char b1[SOME_SIZE];
char (*b3)[3]=(char(*)[3])b1;
so that b3[i][j] == b1[i*3+j]
.
Can I declare such a pointer, b3
, in unsafe
C#?
My intention is to access bitmap channels as:
///...
unsafe {
//...
byte *target; //8bpp
byte (*source)[3]; //24bpp
//...
target[x]=(source[x][0]+source[x][1]+source[x][2])/3;
//...
I hope this way, using source[x][ch]
instead of source[x*3+ch]
to get some compiler optimization.
Upvotes: 9
Views: 7953
Reputation: 26268
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct FastPixel
{
public readonly byte R;
public readonly byte G;
public readonly byte B;
}
private static void Main()
{
unsafe
{
// 8-bit.
byte[] b1 =
{
0x1, 0x2, 0x3,
0x6, 0x7, 0x8,
0x12, 0x13, 0x14
};
fixed (byte* buffer = b1)
{
var fastPixel = (FastPixel*) buffer;
var pixelSize = Marshal.SizeOf(typeof (FastPixel));
var bufferLength = b1.Length / pixelSize;
for (var i = 0; i < bufferLength; i++)
{
Console.WriteLine("AVERAGE {0}", (fastPixel[i].R + fastPixel[i].G + fastPixel[i].B)/pixelSize);
}
}
}
}
}
This should be pretty much identical what you have. Note that I don't expect any performance gains. This is not micro-optimization, it's nano-optimization.
If dealing with huge images, look into parallel programming & SSE and how cache lines work(they have saved me actually 3-4 seconds - crazy right?!)
Upvotes: 7