Newsgroup: it.comp.lang.c
Titolo: Implementazione di una funzione bitblt (Bit Block Transfer)

Ho un array bidimensionale che mi rappresenta il framebuffer di un
display monocromatico:
  unsigned char fb[32][24]
Si tratta di 32 pixel verticali e 192 (24x8) pixel orizzontali. Quindi
8 pixel orizzontali sono memorizzati
contemporaneamente in un byte (il bit più signficativo è quello più a
sinistra del display).
Quindi fb[0][0] rappresenta gli 8 pixel in alto a sx del display (il
bit più significativo è proprio l'estremo).
fb[0][1] rappresenta i successivi 8 pixel immediatamente sulla destra.
ecc. ecc.
A parte ho un altro array monodimensionale che rappresenta una icona
di 24x24 pixel:
  unsigned char icon[] = {
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0xFF, 0x00, 0xFF,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00,
      0x00, 0xFF, 0x00};
Ora mi chiedo come fare per copiare (sostituendo, facendo una AND, OR,
XOR o NOT) questa sequenza di
24x24 pixel in una posizione qualsiasi del framebuffer.
La cosa non è difficilissima nel caso l'icona abbia una lunghezza
orizzontale che sia un multiplo di 8 e debba
essere copiata proprio all'inizio di un byte (coordinata orizzontale
multiplo di 8). Come si potrebbe implementare
una funzione generica che prende una icona di dimensioni (xl,yl) pixel
e la copia alla coordinata (x0,y0) del
framebuffer? Ovviamente cercando di evitare algoritmi troppo banali
come la copia di un pixel alla volta.
Ho fatto qualche ricerca, ma senza successo.


Non sembra difficile... Copi a blocchi di bytes (a seconda del tipo di
processore che usi la dimensione ovviamente varia) shiftando ogni
blocco di quello che serve or-ando l'avanzo del blocco precedente.
Dove hai trovato difficoltà? Se posti il codice magari vediamo gli
errori!
Ciao!

 blocco di quello che serve or-ando l'avanzo del blocco precedente.
Non ho capito. Diciamo che devo copiare l'icona nel punto di
coordinata
(3,0). Per il primo byte fb[0][0] devo cambiare solo i 5 bit meno
significativi
copiandoli dai 5 bit più significativi del primo byte dell'icona icon
[0].
Quindi:
  tmp = icon[0] & ~((1 << 3) - 1);  // ~((1 << 3) - 1) = 1111 1000
  tmp >>= 3;
  fb[0][0] &= ~((1 << 5) - 1);         // ~((1 << 5) - 1) = 1110 0000
  fb[0][0] |= tmp;
Ovviamente 3 è il complemento a 8 di 5.
Questo non è difficilissimo. Ora però devo passare al secondo byte
del framebuffer. Questo deve essere sostituito con i 3 bit meno
significativi di icon[0] e i 5 bit più significativi di icon[1]. E
questo diventa
complicato.
Inoltre devo pure generalizzare il tutto (5 e 3 sono solo esempi) e
metter su i loop opportuni. C'è da perdersi...


Può essere che scrivo una grande cavolata (non ho testato il codice)
ma io fare qualcosa del genere:
void bitblt(x, y)
{
    unsigned char av = x%8;
    unsigned char mk = 0xff<<(8-av);
    /* qui codice per il primo posizionamento */
    /* loop principale */
    for (i=1; i<(x-1); ++i)
        *(fb+i) = ((*(icon+i))<<av) | ((*(icon+(i-1)))&mk);
    /* ultimo posizionamento */
}
a me sembra fattibile - no?
ciao!

 come la copia di un pixel alla volta.
void copia(unsigned char x0,unsigned char y0,unsigned char x,unsigned
char y)
{
   unsigned char i,j,k;
   k=0;
   for(j=y0,j<y,j++) //verticale
   {
       for(i=x0,i<x,i++) //orrizontale
       {
           fb[j][i] = icon[k];
           k++;
       }
   }
}
in questo caso fb e icon sono globali.
oppure non ho capito com'e' la situazione.
Ciao Jack

 a me sembra fattibile - no?
In effetti hai ragione, non è difficilissimo se si nota che ci sono
solo due
spostamenti di un gruppo di bit agli estremi del byte (a sinistra
oppure a
destra) e questo ti permette di evitare anche molti mascheramenti.
Grazie della dritta...

 }
Questo funziona se i byte sono tutti allineati e multipli di 8.
La cosa si complica quando devi copiare icon[] in fb[] non allineato
al byte.

 al byte.
ah ok, avevo capito che era un display alfanumerico, non a matrice.
Ciao Jack