2010-08-10 6 views
5

J'ai lu le livre "C.Sharp 3.0 in a Nutshell" et j'ai rencontré le code suivant, qui m'intéressait. travailComment fonctionne ce code dangereux?

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

Quelqu'un pourrait-il me expliquer comment ce "* p ++ & = 0xFF"?

Répondre

9

Cette fonction est censée prendre une image bitmap et filtrer toutes les couleurs sauf le rouge.

Cela suppose qu'il s'agit d'une image bitmap 32 bits, où chaque pixel est représenté par int. Vous déréférencer l'emplacement de mémoire actuellement pointé par p (qui est un int), et l'ET avec 0xFF, qui laisse effectivement seulement la composante rouge du pixel (en supposant que l'octet le plus bas est le composant rouge). Vous incrémentez également automatiquement le pointeur sur le int suivant (avec ++). Est-ce que cela répond?

+0

Merci pour l'explication.Oui, toutes les réponses sont très utiles. –

+0

Alors pourquoi ne pas accepter la réponse? –

6

Il est le même que celui (OMI l'affaire *p++ &= 0xFF; originale est un peu méchant - c'est une ligne de code qui est fait deux choses):

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

Une expression comme a = a & 0xFF ensembles tous, mais les 8 bits inférieurs de la variable a à zéro.

+0

Merci pour l'explication. –

1

Ce code incrémente le pointeur p, le faisant pointer vers le pixel suivant dans le bitmap, puis masque tout sauf l'octet le moins significatif, qui, dans le format Microsoft BMP (et je suppose dans d'autres implémentations non standard) est dans BGR format.

Cela a pour effet de supprimer tous les composants de couleur sauf le rouge.

+0

Merci pour l'explication. –

1

Comme vous le savez probablement,

x &= y 

est le même que

x = x & y

Un 'int' ANDED avec '0xff' active tous les bits dans le supérieur 3 octets à zéro (un masque).

Le askterisk est déréférencement du pointeur, de sorte

*p 

est un nombre entier. 'Post increment' met à jour la valeur actuelle du pointeur pour pointer vers l'entier suivant dans la mémoire

Ainsi, au total, le code parcourra les entiers 'length' en mémoire, et masquera tout sauf l'octet le plus bas (c'est-à-dire, l'octet 'rouge' s'il s'agit de valeurs de couleur [A] BGR).

+0

Merci pour l'explication. –

2

C'est le genre de syntaxe que vous trouverez dans le langage C, mal vu mais pas rare. Écrit:

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

Cela dépend du format bitmap si cela fonctionne bien. Généralement, le code réinitialise l'alpha des pixels à zéro. Produire une image noire.

+0

Merci pour l'explication. –

Questions connexes