How does this unsafe code work?
I read the "C.Sha开发者_StackOverflow社区rp 3.0 in a Nutshell" book and met the next piece of code, that interested me.
unsafe void RedFilter(int[,] bitmap)
{
int length = bitmap.Length;
fixed (int* b = bitmap)
{
int* p = b;
for(int i = 0; i < length; i++)
*p++ &= 0xFF;
}
}
Could anyone explain me how does this "*p++ &= 0xFF" work?
The function is presumably meant to take a bitmap image, and filter out all the colors except red.
This assumes that it's a 32-bit bitmap, where each pixel is represented by an int
.
You're dereferencing the memory location currently pointed to by p
(which is an int
), and ANDing it with 0xFF
, which effectively leaves only the red component of the pixel (assuming that the lowest byte is the red component). You're also automatically incrementing the pointer to the next int
(with ++
). Does that answer it?
It's the same as this (IMO the original *p++ &= 0xFF;
trick is a little nasty -- it's one line of code that's doing two things):
*p = *p & 0xFF;
p++;
An expression like a = a & 0xFF
sets all but the bottom 8 bits of variable a
to zero.
It's the kind of syntax you'd find in the C language, frowned upon there as well but not uncommon. Written out:
int temp = *p;
temp = temp & 0x000000ff;
*p = temp;
p = p + 1; // Move pointer by 4 bytes.
It depends on the bitmap format if this will work out well. Not commonly, the code resets the alpha of the pixels to zero. Producing a black image.
This code increments the pointer p, making it point to the next pixel in the bitmap, then masks off everything but the least significant byte, which, in Microsoft BMP format (and I assume in other nonstandard implementations) is in BGR format.
This has the effect of removing all of the color components except for red.
As you probably know,
x &= y
is the same as
x = x & y
An 'int' anded with '0xff' will set all the bits in the higher 3 bytes to zero (a mask).
The askterisk is dereferencing the pointer, so
*p
is an integer.
The 'post increment' updates the actual pointer value to point to the next integer in memory.
So in total, the code will run through 'length' integers in memory, and mask out all but the lowest byte (i.e., the 'red' byte if these are [A]BGR colour values).
精彩评论