| Herd Software Entwicklung
|=
DaVinci Grafikbibliothek
|==
DaVinci Dokumentation Home Search Order


DIB Device-Independend-Bitmaps

Konzept

DIB (Device Independent Bitmap) ist der Ausdruck für eine Bitmap in einem einheitenunabhängigen Format. Eine DIB ist ein Speicherbereich mit einer gemäß der Windows API-Definition vorgegebenen Struktur. Die notwendigen Angaben bestehen aus verschiedenen auszufüllenden Strukturen für Header, Farbpalette und Pixeldaten, die nacheinander in einem Speicherblock abgelegt werden. Der Speicherblock wird mit der Windows-Funktion GlobalAlloc zugeordnet, das von GlobalAlloc zurückgegebene Handle ist das DIB-Handle mit dem Typ HDIB.

Aufbau des Datenblocks

Die Beschreibung dieses Datenformates kann in der Windows-Dokumentation unter BITMAPINFOHEADER nachgesehen werden.

Sowohl in .BMP-Dateien, als auch in den Ressourcen-Dateien werden Bitmaps als DIB abgelegt (Bei .BMP-Dateien ist noch eine BITMAPFILEHEADER-Struktur vorangestellt).

Die Bezeichnung "einheitenunabhängig" impliziert nun nicht, daß das DIB-Datenformat keine Rücksicht auf unterschiedliche Farbtiefen etc. nehmen muß.

Mit Windows 3.0 als Standard definiert sind die Farbtiefen 1,4,8 und 24 Bit Farbtiefe. Außerdem werden unter Windows NT und Windows 95 noch DIBs mit 16 und 32 Bit Farbtiefe definiert, wobei die 16-Bit Farbtiefe von DaVinci nur eingeschränkt unterstützt wird.

Es existiert ein hervorragender "Self-Study-Guide" von Microsoft zum DIB-Datenformat, der u.a. aus Compuserve geladen werden kann, Dateigröße ca.. 1 MByte.

Im Gegensatz zu einer DDB enthält eine DIB alle zur Anzeige des Bildes erforderlichen Farbinformationen (Farbpalette, s.u.). DIBs können in unterschiedlichen Farbauflösungen (2,16,256,16777216 Farben) vorliegen, unabhängig vom auf dem Rechner installierten Grafikkartentreiber.

Von DaVinci importierte Bilder liegen im Format einer DIB vor. Zur Darstellung wird ein globales Speicherhandle von Windows benutzt, das mit der Funktion GlobalAlloc erstellt wurde. Es ist vom Windows-Variablentyp HGLOBAL, jedoch verwendet DaVinci aus Dokumentationsgründen den äquivalenten Namen HDIB.

In vielen Fällen genügt es, die DIB einfach in eine DDB umzuwandeln. Die dazu benötigen Routinen finden Sie im Modul Leonardo. Beachten Sie bitte, daß eine DDB aber nicht an einen Drucker übergeben werden kann, denn schließlich ist sie einheitenabhängig.

Um aus diesem globalen Handle auf die Daten innerhalb der DIB zuzugreifen, benötigen Sie die Windows-Funktion GlobalLock. Diese liefert als Rückgabewert einen Zeiger auf die erste Struktur im DIB-Speicherblock, also die BITMAPINFOHEADER -Struktur.

Der prinzpielle Aufbau einer DIB ist definiert durch die folgenden Strukturen:

Bei DIBs im Speicher DIBs in einer BMP-Datei OS/2 1.x-Format Windows 95/NT-Erweiterung
Entfällt BITMAPFILEHEADER BITMAPFILEHEADER BITMAPFILEHEADER
BITMAPINFOHEADER BITMAPINFOHEADER BITMAPCOREHEADER BITMAPINFOHEADER
mehrere RGBQUAD mehrere RGBQUAD Mehrere RGBTRIPLE mehrere RGBQUAD
Bitmap-Daten Bitmap-Daten Bitmap-Daten Bitmap-Daten

Die Anzahl der RGBQUAD -Strukturen wird vom Element biClrUsed der BITMAPINFOHEADER -Struktur bestimmt. Ist es null, so bestimmt das Element biBitCount die Anzahl der RGBQUAD-Strukturen:

biBitCount Anzahl RGBQUAD-Strukturen

1 2

4 16

8 256

16* 0*

24 0

32* 0*

Am Einfachsten ergibt sich die Anzahl der RGBQUAD-Strukturen gemäß:

(WORD) (1 << bmi.biBitCount).

* biBitCount -Werte von 16 und 32 wurden für Windows 3.x nicht definiert, sie wurden mit Video für Windows und Windows NT 3.5 / Windows 95 eingeführt. DaVinci und Leonardo unterstützen DIBs mit biBitCount =16 nur eingeschränkt, aber die Funktion TransformDIB kann zur Umwandlung einer DIB in diesem Format in eine DIB mit biBitCount = 24 herangezogen werden.

Für Pascal-Programmierer ist es wichtig, daß Borland den Strukturdefinitionen häufig ein T vorangestellt hat, dies aber in der Dokumentation nicht systematisch berücksichtigt wurde:

Pascal/Delphi-Schreibweise

C-Name Pascal-Name

BITMAPINFOHEADER TBitmapInfoHeader

LPBITMAPINFOHEADER PBitmapInfoHeader

RGBQUAD TRgbQuad

LPRGBQUAD PRgbQuad

Die Bitmap-Daten der DIB folgen auf die RGBQUAD -Strukturen. Sie beginnen mit der untersten Abtastzeile. Zwischen den Zeilen sind so viele unbenutzte Bytes, daß die nächste Zeile wieder auf einer durch 4 teilbaren Adresse beginnt:
WidthBytes = (bih.biWidth * bih.biBitCount + 31) / 32 * 4;

Datenbits

1-Bit Format (Monochrom)

Bei biBitCount == 1 werden die Pixel Bitweise abgespeichert, 8 Pixel in einem Byte. Das erste Pixel wird in Bit 7 des ersten Bytes abgespeichert, das zweite Pixel in Bit 6 etc. Ein gesetztes Bit bedeutet die Farbe des zweiten Paletteneintrags, ein gelöschtes Bit die Farbe des 1. Paletteneintrags (RGBQUAD-Strukturen).

Um ein bestimmtes Bit innerhalb einer Pixelzeile zu adressieren, können Sie folgendermaßen vorgehen:
UINT	XInLine;
HPBYTE	hpStartOfLine;

HPBYTE	hpPixelInLine = hpStartOfLine + XInLine / 8;
BYTE	PixelInByte   = 7 - (XInLine % 8);
BOOL	IsPixelSet;

IsPixelSet = (*hpPixelInLine >> PixelInByte) & 1;

// Nächstes Pixel:
if (PixelInByte)
	PixelInByte--;
else 
{
	hpPixelInLine++;
	PixelInByte = 7;
}
4-Bit Format (VGA)

Bei biBitCount == 4 werden jeweils zwei die Pixel in einem Byte gespeichert. Das erste Pixel wird in Bits 7-4 des Bytes abgespeichert, das zweite Pixel in Bits 3-0 etc. Die 4 Bits geben jeweils die Nummer des Farbpaletteneintrags an.

8-Bit Format (256 Farben)

Bei biBitCount == 8 wird für jedes Pixel ein Byte belegt. Es gibt die Nummer des zu verwendenden Farbpaletteneintrags an.

24-Bit Format (TrueColor)

Falls Daten im Datenformat 24-Bit vorliegen (biBitCount == 24), so besteht ein Pixel aus drei Bytes in der Reihenfolge Blau, Grün, Rot. Eine Farbpalette kann zusätzlich angegeben werden, um den Zeichenvorgang für Windows zu beschleunigen, in diesem Falle ist biClrUsed nicht 0.

32-Bit Format

Falls Daten im Datenformat 32-Bit vorliegen (biBitCount == 32), so besteht ein Pixel aus vier Bytes in der Reihenfolge Blau, Grün, Rot und einem unbenutzten Byte. Das 32-Bit DIB-Format läßt sich besonders leicht und schnell verarbeiten, daher steht die Funktion ConvertDIB zur Verfügung.. Þ Vereinfachte Verarbeitung mit 32-Bit DIBs

Strukturen in einem DIB Datenblock auffinden

Um gezielte Veränderungen an DIB-Daten durchzuführen muß Ihre Anwendung die Adressen von Zeigern auf die verschiedenen Strukturen einer DIB berechnen können.
LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) GlobalLock( hDIB );
LPRGBQUAD            lprgbquad = (LPRGBQUAD) ((LPSTR) lpbmi + lpbmi->biSize);
LPSTR                lpBitmapBits = ((LPSTR) lprgbquad)+DIBPaletteSize(lpbmi);
int                  WidthOfLineInBytes = (lpbmi->biWidth * lpbmi->biBitCount + 31) / 32 * 4;
LPSTR                lpStartOfLine = lpBitmapBits + y * WidthOfLineInBytes,
                     lpStartOfPixel = lpStartOfLine + x * lpbmi->biBitCount / 8;

HUGE-Zeiger Adressierung

Da DIB-Speicherbereiche regelmäßig mehr als 64 KBytes Daten umfassen, müssen zu ihrer Adressierung Zeiger der Klasse "huge" verwendet werden. Da Delphi 1.0 keine huge Zeiger unterstützt, ist es zur Entwicklung entsprechender Anwendungen weitgehend ungeeignet.

Beachten Sie auch die Unit GETDIB.PAS und das Beispiel GETTEST.PAS. Sie zeigen, wie DIB-Daten im Pascal/Delphi 1.0-Anwendungsprogramm angesprochen werden können.

Historie der DIB-Spezifikationen

Die ursprünglich mit Windows 3.0 eingeführte Spezifikation des DIB Datenformates war recht grundlegend. Microsoft hat die DIB-Spezifikation mehrfach mit optionalen Erweiterungen versehen.

Windows NT 3.1 und Video For Windows 1.1 unter Windows 3.1
Windows NT 4.0 und Windows 95

Þ Vereinfachte Verarbeitung mit 32-Bit DIBs