Dateiformat: ICO und CUR
Hinweis: der Pfad "garage.gif" wurde nicht gefunden!
Stand: 20.11.2005
15.08.2005: Durch einen Beitrag im Delphi-PRAXiS Forum bin ich letztens wieder dazu gekommen, mich mit dem Format von Windows Icons und Cursorn zu befassen. Die meisten Dokumente, die man im Internet dazu findet, stammen aus der Zeit, als Icons noch maximal 256 Farben hatten (oder davor). Darum hier eine kleine Formatbeschreibung. 20.11.2005: Endlich bin ich dazu gekommen, etwas weiter zu arbeiten. Es fehlen aber immer noch viele Dinge und das ganze Dokument ist eher noch eine Fakten- und Gedankensammlung. Die Gliederung der Informationen werde ich noch überarbeiten. BeschreibungAnders als Bitmaps oder viele andere Grafikdateiformate können Icons und Cursor mehrere Einzelbilder beinhalten, die das System je nach benötigter Auflösung und Farbtiefe benutzt. So können in einer einzigen ICO-Datei z.B. Bilder für die Größen 16x16, 32x32, 48x48 und die Farben 16, 256 und Truecolor enthalten sein. Außerdem können Icons und Cursor transparent dargestellt werden und auch eine das ursprüngliche Bild invertierende Wirkung haben, weshalb zusätzlich zu den eigentlichen Bilddaten noch eine Maske in der Größe des Icons bzw. Cursors abgespeichert wird.
Zur Darstellung des Icons bzw. des Cursors wird das ursprüngliche Bildschirminhalt zunächst über AND mit der Maske verknüpft und danach über XOR mit dem Bild. Insgesamt lassen sich mit der Kombination von Maske und Bild drei Effekte erzielen. Diese werden deutlich, wenn wir uns eines der Ergebnisbilder noch einmal genauer ansehen:
Die drei markierten Bereiche auf den Bildern zeigen die unterschiedlichen Effekte:
Fehlt: Windows-XP-Icons (alphablending) DateiformatEine ICO- oder CUR-Datei besteht aus dem Dateiheader, dem Verzeichnis der Einzelbilder für den schnellen Zugriff und den einzelnen Daten für jedes Einzelbild. Da Icons und Cursor bis auf kleine Unterschiede dasselbe Dateiformat benutzen, werde ich sie hier auch zusammen beschreiben. DateiheaderDie Datei besitzt zunächst einen kleinen Header von 6 Byte Größe, der den Dateityp und die Anzahl der enthaltenen Teilbilder angibt:
Oder als Typdeklaration für C/C++ bzw. Pascal:
Hinweis: Für C/C++ müsste noch etwas wie "#pragma packed(1)" hinzugefügt werden. Verzeichnis der EinzelbilderAuf diesen Header folgt das Verzeichnis der Einzelbilder, also idCount Datenblöcke mit der folgenden Struktur, die jeweils 16 Byte groß sind:
Oder auch dies als Typdeklaration für C/C++ bzw. Pascal:
Im Falle eines Icons können die Werte für wPlanes und wBitCount auch 0 sein, da sie ohne Probleme aus dem Bitmapinfo-Header des Einzelbildes ermittelt werden können und für die Auswahl des Bildes zunächst irrelevant sind; wichtig sind die Breite, die Höhe und die Anzahl der Farben. Für Cursor werden diese Felder sowieso »missbraucht« und dort werden die X- und Y-Koordinaten des Hotspots gespeichert. Der Hotspot ist der Punkt des Bildes - von links oben gerechnet - der die Spitze des Mauszeiger repräsentiert. Dies muss nicht immer die linke obere Ecke sein, wie man sich leicht am Beispiel eines Fadenkreuzes deutlich machen kann. BilddatenDie eigentlichen Bilddaten findet man für jedes Einzelbild in der Datei ab Offset dwImageOffset mit einer Größe von dwBytesInRes Bytes. Die Bilddaten sind — wohl aus historischen Gründen — etwas unglücklich gespeichert. An sich geht es ganz normal los mit einer BITMAPINFOHEADER Struktur wie sich auch am Anfang von BMP-Dateien gespeichert wird. Diese Struktur besteht aus den folgenden Feldern:
Die Typdeklaration für BITMAPINFOHEADER steht in den Windows API Deklarationsdateien. Die wirkliche Größe der Struktur ist nicht fest, sondern steht im Feld biSize. Auf die Angabe im Feld biSizeImage kann man sich nicht verlassen; manche Anwendung speichern hier Größe der Pixeldaten für beide Bitmaps und manche nur für die erste. Sofern das Bild eine Palette hat, also wenn biClrUsed größer als 0 ist oder wenn biBitCount kleiner oder gleich 8 ist, dann folgt auf diese Struktur ein Array mit ebensovielen RGBQUAD Farbeinträgen. Danach folgen die wirklichen Pixeldaten des Bildes, deren Format abhängig von den Angaben im BITMAPINFOHEADER sind. Für die Verarbeitung der Pixeldaten ist es wichtig zu beachten, dass der BITMAPINFOHEADER, die Palette und die eben beschriebenen Pixeldaten zusammen exakt das Format einer geräteunabhängigen Windows-Bitmap haben, mit der einzigen Ausnahme, dass das Feld biHeight falsch ist und eben die doppelte Höhe der Bitmap angibt. Direkt im Anschluss an die Pixeldaten des Bildes kommen die der monochromen Maske des Icons. Zu diesen Pixeldaten könnte man sich den folgenden BITMAPINFOHEADER erzeugen:
Hinweis: biSizeImage wird hier einfach aus der Größe der Bitmap berechnet unter der Vorgabe, dass jede Scanzeile der Bitmap auf einer 4-Byte-Grenze liegen muss (32 Bits). Dazu gehört dann noch eine Farbpalette mit zwei Einträge: Schwarz (Index 0) und Weiß (Index 1). AusblickHier schließe ich für heute, bald gibt's mehr Infos zusammen mit einigen Beispielprogrammen. Weiterführende Informationen
|