Beispiel 3:

setzen
   vgamem [i]=63;
  }
     vga_getch();
// Zurrück zum Textmode
     vga_setmode (TEXT);
}


uns nun der ersten sinnvollen Aufgabe dieses Kurses zu. Wer Spiele oder Demos programmieren möchte muss Grafiken von der Festplatte laden und diese anzeigen können. Deshalb werden wir uns nun mit dem Bildformat BMP befassen und eine Grafik auf unserm Bildschirm anzeigen. Der Kopf einer BMP-Datei besteht aus dem Datei-Header und dem Bitmap-Info-Block. Im Header steht eingentlich nur die Formatkennung (BM) und die Dateilänge. Die Eigentlichen Daten übers Bild (Höhe, Breite, Farbtiefe, etc. speichert das Bitmapformat im Info-Block.

Der BMP-Header:

00H    2    Dateikennung 'BM'
02H    4    Dateilänge in Byte
06H    4    reserviert (muß 0 sein)
0AH    4    Offset des Datenbereiches


Interessante Werte im sind unteranderm Breite und Höhe, also die Ausmaße unseres Bildes. Das Feld Farbebenen stammt wohl noch aus der Zeit als Grafikkarten Farben über Colorplanes realisierten und ist heute völlig uninterresannt. Im nächsten Feld wird die Farbtiefe der Bitmap (16 (4),256(8) Farben oder TrueColor (24)) festgelegt.

Der BMP-Info-Block

0EH 4 Länge des Info-Blockes in Byte (28 00 00 00)
12H 4 Breite des Bildes in Pixeln
16H 4 Höhe des Bildes in Pixeln
1AH 2 Farbebenen (muß 1 sein)
1CH 2 Zahl der Bits pro Pixel
1EH 4 Typ der Komprimierung (normalerweise 0)
22H 4 Größe des Bitmap-Datenbereiches in Byte
26H 4 horizontale Auflösung
2AH 4 vertikale Auflösung
2EH 4 Zahl der benutzten Farben (normalerweise 0)
32H 4 Zahl der wichtigen Farben (normalerweise 0)

Eine Kopremmierung ist nur bei 16 und 256 Farben Bildern möglich. Die bei kopremierten Bildern benutzte Kompression ist die sogenannte Lauflängen-Codierung (Run-Length-Encoding (RLE)). Sie faßt aufeinanderfolgende Gleiche Bytes zusammen (statt 55 00 00 00 00 00 wird 55 5x 00 gespeichert). Nach dem Info-Block sind die Bilddaten abgespeichert. Da wir nur mit Truecolor-Bildern arbeiten sind
Kompresion und Paletten für uns nicht wichtig. Von bedautung ist aber das die Bilddaten Spiegelverkehrt gespeichert werden. Da war wohl ein leitender MS Mitarbeiter besoffen. Unser ganz einfaches Beispielprogramm zeigt ein 800x600x16M BMP-Bild auf dem Bildschirm an. Kompiliert wird das ganze mit gcc -lvga -lstdc++ ZeigBMP.cpp.
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <vga.h>
class BMP
{
public:
unsigned char *Bilddaten;
unsigned int Breite;
unsigned int Hoehe;
unsigned int bpp;

private:
unsigned char *Data;
public: open (char *Bildname); };
BMP::open (char *Bildname)
{
FILE *datei;
char c;
unsigned char Datum [6];
datei = fopen (Bildname,"r");
if (!datei) { printf ("Datei nicht gefunden. \n"); exit (0);}
fread (&Datum,1,6,datei);
cout << Bildname;
printf("\n Kennung : %c%c \n",Datum[0],Datum[1]);
unsigned int Filelaenge=Datum[5]*256*256*256+Datum[4]*256*256+Datum[3]*256+Datum[2];
printf("\n Länge : %u \n",Filelaenge);
fclose (datei);
Data = (unsigned char *) malloc (Filelaenge);
datei = fopen (Bildname,"r");
fread (Data,1,Filelaenge,datei);
fclose (datei);
Breite=(unsigned int) (Data[21]*256*256*256+Data[20]*256*256+Data[19]*256+Data[18]);
Hoehe=(unsigned int) (Data[25]*256*256*256+Data[24]*256*256+Data[23]*256+Data[22]);
bpp=(unsigned int) (Data[29]*256+Data[28]);
Bilddaten=Data + (unsigned int) (Data[13]*256*256*256+Data[12]*256*256+Data[11]*256+Data[10]);
}

main ()
{
BMP MeinBild;
MeinBild.open("TestBild.bmp");
vga_setmode(G800x600x64K);
unsigned int i,j,c;
short* vgamem;
vgamem= (short *) graph_mem;
c=0;
for (j=0;j<600;j++)
for (i=0;i<800;i++)
{
vgamem [800*600-800*j+i]= MeinBild.Bilddaten [c]/8+MeinBild.Bilddaten[c+1]/4*32
+MeinBild.Bilddaten[c+2]/8*32*64 ;
c=c+3;
}
vga_getch();
vga_setmode(TEXT);
}