BITMAPFILEHEADER und BITMAPINFOHEADER Strukturen...



  • Hi,

    wenn ich unter Windows eine Bitmap selbst erstellen und abspeichern will, kann ich ja die beiden oben genannten Strukturen ausfüllen, diese an den Anfang einer Datei schreiben und anschließend meine Bilddaten schreiben. Das funktioniert auch wunderbar. Allerdings soll mein Programm plattformunabhängig sein, deshalb habe ich mir die beiden Strukturen selbst definiert, genauso wie sie in der Dokumentation stehen. Das sieht bei mir unter Win32 dann so aus:

    typedef struct tagBITMAPFILEHEADER {
    	unsigned short    bfType;
    	unsigned long     bfSize;
    	unsigned short    bfReserved1;
    	unsigned short    bfReserved2;
    	unsigned long     bfOffBits;
    } BITMAPFILEHEADER;
    
    typedef struct tagBITMAPINFOHEADER{
    	unsigned long      biSize;
    	long		   biWidth;
    	long	           biHeight;
    	unsigned short     biPlanes;
    	unsigned short     biBitCount;
    	unsigned long      biCompression;
    	unsigned long      biSizeImage;
    	long	           biXPelsPerMeter;
    	long               biYPelsPerMeter;
    	unsigned long      biClrUsed;
    	unsigned long      biClrImportant;
    } BITMAPINFOHEADER;
    

    Original stehen folgende Datentypen da:
    - DWORD anstelle von unsigned long
    - WORD anstelle von unsigned short
    - LONG anstelle von long

    Da ich aber unter Win32 bin, sind die oben genannten Typen (also DWORD,WORD,LONG) aber exakt so als Typedef definiert wie ich es jetzt geschrieben habe, deshalb sollte das ja keine Probleme geben.

    Tja und das Problem ist jetzt halt, dass so doch nicht funktioniert. Die Bitmaps die damit erstellt werden können nicht geöffnet werden, weil irgendwas mit dem Bitmap-Header nicht stimmt. Ich hab nur absolut keine Ahnung woran das liegen könnte. Jemand eine Idee?



  • Ich würde zuallererst das Padding prüfen.



  • Erstens: Padding (zumindest für die Header-Typen) ausschalten - sonst kommt der Compiler auf die Idee, Füllbytes zwischen die Daten zu quetschen (z.B. zwischen bfType und bfSize).

    Zweitens: short und long sind laut Standard mindestens 2 bzw. 4 Byte groß, dürfen aber auch größer sein - du brauchst int-Typen, die genau 2 (WORD) bzw. 4 (DWORD/LONG) Byte groß sind.

    Drittens: Hast du die Header auch korrekt mit Werten gefüllt (z.B. bfType==19778 ("BM") oder biSize==40)?



  • Argh, hab gar nicht an das Padding gedacht.
    Lag am Padding. Jetzt funktioniert es.
    Danke 🙂



  • Mal so interesse halber:

    Wie schaltet man das Padding denn ab?



  • #pragma pack(1) // Ausrichtung auf Byte-Grenzen (Padding ausschalten)
    struct xyz      // Strukturen deklarieren
    {
    ...
    };
    #pragma pack()  // Standard Padding wieder herstellen
    


  • Wissen haben wollender schrieb:

    Wie schaltet man das Padding denn ab?

    Das hängt vom verwendeten Compiler ab (Zausel's Variante ist für den MSVC gültig).



  • was gibts denn sonst noch für varianten



  • Der BCC akzeptiert die MSVC-Padding-Anweisungen auch. Wer es ganz sauber machen möchte, sollte aber folgendes verwenden:

    #ifdef __BORLANDC__
     #pragma pack(push, n)
    #endif
    
    ...
    
    #ifdef __BORLANDC__
     #pragma pack(pop)
    #endif
    

    Dadurch wird das Padding hinterher nicht auf den Default- sondern auf den zuletzt eingestellten Wert gesetzt.



  • Beim g++ schreibt man einfach hinter jedes Attribut __attribute__((packed)).
    Hab ich zumindest bei mir gemacht und hat funktioniert.



  • Ui!
    Das es verschiedene Versionen zum 'Paddig abschalten' gibt wusste ich noch gar nicht.
    Dann wäre es wohl doch besser, der Portabilität zu liebe, Paddinbytes zu benutzen ?
    Aber auf was ausrichten, auf 4Byte-Grenzen ? 😕


Anmelden zum Antworten