2010-08-10 14 views
5

Leí el libro "C.Sharp 3.0 in a Nutshell" y conocí el siguiente fragmento de código que me interesó.¿Cómo funciona este código inseguro?

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; 
     } 
    } 

¿Alguien podría explicar cómo funciona esto "* p ++ & = 0xFF" trabajo?

Respuesta

9

Se supone que la función es tomar una imagen de mapa de bits y filtrar todos los colores excepto el rojo.

Esto supone que se trata de un mapa de bits de 32 bits, donde cada píxel está representado por un int. Está desreferenciando la ubicación de memoria señalada actualmente por p (que es int) y ANDing con 0xFF, que efectivamente deja solo el componente rojo del píxel (suponiendo que el byte más bajo es el componente rojo). También está incrementando automáticamente el puntero al próximo int (con ++). ¿Eso lo contesta?

+0

Gracias por su explicación.Sí, todas las respuestas son muy útiles. –

+0

¿Por qué no acepta la respuesta? –

6

Es lo mismo que esto (OMI el original truco *p++ &= 0xFF; es un poco desagradable - es una línea de código que está haciendo dos cosas):

*p = *p & 0xFF; 
p++; 

una expresión como a = a & 0xFF conjuntos de todos pero el fondo 8 bits de la variable a a cero.

+0

Gracias por la explicación. –

1

Este código incrementa el puntero p, haciendo que apunte al siguiente píxel en el mapa de bits, luego enmascara todo menos el byte menos significativo, que en formato BMP de Microsoft (y supongo en otras implementaciones no estándar) está en BGR formato.

Esto tiene el efecto de eliminar todos los componentes de color excepto el rojo.

+0

Gracias por la explicación. –

1

Como usted probablemente sabe,

x &= y 

es lo mismo que

x = x & y

Un 'int' AND con '0xFF' para poner todos los bits en la mayor 3 bytes a cero (una máscara).

El askterisk se dereferencing el puntero, por lo

*p 

es un número entero.

El 'incremento de publicación' actualiza el valor real del puntero para apuntar al siguiente entero en la memoria.

En total, el código se ejecutará en enteros de 'longitud' en la memoria y enmascarará todos menos el byte más bajo (es decir, el byte 'rojo' si estos son valores de color [A] BGR).

+0

Gracias por la explicación. –

2

Es el tipo de sintaxis que encontrarías en el lenguaje C, fruncido el ceño también pero no poco común. Escrito fuera:

int temp = *p; 
temp = temp & 0x000000ff; 
*p = temp; 
p = p + 1; // Move pointer by 4 bytes. 

Depende del formato de mapa de bits si esto funcionara bien. No comúnmente, el código restablece el alfa de los píxeles a cero. Produciendo una imagen negra.

+0

Gracias por la explicación. –

Cuestiones relacionadas