2010-08-10 12 views
5

Ho letto il libro "C.Sharp 3.0 in a Nutshell" e ho incontrato il prossimo pezzo di codice, che mi interessava.Come funziona questo codice non sicuro?

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

Qualcuno mi potrebbe spiegare il lavoro come fa questo "* p ++ & = 0xFF"?

risposta

9

La funzione è presumibilmente pensata per acquisire un'immagine bitmap e filtrare tutti i colori tranne il rosso.

Si presume che sia una bitmap a 32 bit, in cui ogni pixel è rappresentato da un int. Si sta interrompendo la posizione di memoria attualmente indicata da p (che è un int) e ANDinvia con 0xFF, che lascia effettivamente solo il componente rosso del pixel (presupponendo che il byte più basso sia il componente rosso). Stai anche incrementando automaticamente il puntatore al prossimo int (con ++). Questo risponde?

+0

Grazie per la spiegazione.Sì, tutte le risposte sono molto utili. –

+0

Allora perché non accettare la risposta? –

6

E 'lo stesso di questo (IMO l'originale *p++ &= 0xFF; trucco è un po' brutto - è una riga di codice che sta facendo due cose):

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

Un'espressione come a = a & 0xFF set di tutti, ma gli 8 bit di fondo della variabile a a zero.

+0

Grazie per la spiegazione. –

1

Questo codice incrementa il puntatore p, facendo in modo che punti al pixel successivo nella bitmap, quindi nasconde tutto tranne il byte meno significativo, che nel formato Microsoft BMP (e presumo in altre implementazioni non standard) è in BGR formato.

Questo ha l'effetto di rimuovere tutti i componenti del colore tranne il rosso.

+0

Grazie per la spiegazione. –

1

Come probabilmente sapete,

x &= y 

è lo stesso di

x = x & y

Un 'int' AND con '0xff' imposterà tutti i bit in alto 3 byte a zero (una maschera).

L'askterisk è dereferenziazione il puntatore, quindi

*p 

è un numero intero.

Il "post-incremento" aggiorna il valore del puntatore effettivo in modo che punti al numero intero successivo in memoria.

Quindi, in totale, il codice eseguirà gli interi "di lunghezza" nella memoria e maschererà tutto tranne il byte più basso (cioè il byte "rosso" se questi sono [A] valori di colore BGR).

+0

Grazie per la spiegazione. –

2

È il tipo di sintassi che si trova nel linguaggio C, anche se non è raro. Scritto:

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

Dipende dal formato bitmap se questo funziona correttamente. Non comunemente, il codice reimposta l'alfa dei pixel a zero. Produrre un'immagine nera.

+0

Grazie per la spiegazione. –

Problemi correlati