Bitmap-Header einlesen



  • Deine Idee würde zwar funktionieren, aber ich würde gerne eine plattformunabhänige BitmapKlasse schreiben (nur so zum Üben). Deswegen verwende ich auch nicht die WinAPI-Funktionen dazu. Wie kann ich denn dieses Padding verhindern?



  • Compilerabhängig 🤡
    Mit VS:

    #include <pshpack2.h> // auf 2 Byte ausrichten
    // Struktur
    #include <poppack.h> // alten Zustand wiederherstellen
    

    Compilerunabhängig geht es natürlich auch, dann müsstest du bspw. eigene Header mit entsprechenden #ifdefs erstellen. Aber wie z.B. gcc das Padding regelt, weiß ich nicht, dies sollte jedoch nach kurzer Internetrecherche klar werden.



  • danke euch, klappt jetzt super!

    struct TBitmapHeader
    {
        char lpcIdentifier[2];
        unsigned int iFileLength;
        unsigned int iReserverd;
        unsigned int lpBmpData;
    }__attribute__ ((packed));
    


  • WinNoob schrieb:

    Deine Idee würde zwar funktionieren, aber ich würde gerne eine plattformunabhänige BitmapKlasse schreiben (nur so zum Üben). Deswegen verwende ich auch nicht die WinAPI-Funktionen dazu. Wie kann ich denn dieses Padding verhindern?

    Wenn du's plattformunabhängig willst, dann vergiss das mit der Struktur und lies die Elemente einzeln ein. Selbst dabei musst du schon aufpassen von wegen Endianess...



  • Ich habe mich falsch ausgedrückt. Eigentlich programmiere ich auf Windows, aber ich würde mich gerne auch mal an Linux versuchen. Ich denke mal, dass die Endianess zumindest unter den x86-Systemen gleich bleibt.



  • Wenn du den Code portabel halten willst, kannst du jedenfalls nicht mit __attribute__ oder #pragma arbeiten, das das alles compilerspezifische Dinge sind.
    Da kannst du es also gleich ordentlich lösen und eben die Elemente einzeln lesen statt als struct...



  • Danke dir für die Tipps! Gibt es eine "Anleitung", in der steht, was man beim plattformunabhänigen Programmieren beachten muss? Ich dachte es würde genügen, wenn ich mich an die Standardlibraries halte, aber anscheinend ist ja dem nicht so...



  • Wieso sollte dem nicht so sein!? Das was Standard ist, ist auch portabel. Das Problem ist, dass Dinge wie __attribute__ bzw. das genaue Speicherlayout von structs etc. eben nicht Standard und damit nicht beliebig portabel sind.
    Daher mein ich ja: Wenn du den Code richtig portabel halten willst, lies den Header nicht in ein struct ein, sondern lies die einzelnen Elemente einzeln und verwend dabei am besten die Typen aus <cstdint> um garantiert die richtigen Größen zu haben. Selbst das ist noch nicht wirklich portabel wegen Endianess, aber zumindest schonmal besser als nix 😉



  • mapper schrieb:

    Compilerabhängig 🤡
    Mit VS:

    #include <pshpack2.h> // auf 2 Byte ausrichten
    // Struktur
    #include <poppack.h> // alten Zustand wiederherstellen
    

    Oder gleich

    #pragma pack(push, 2) // bzw. gleich besser 1
    
    // Struktur
    
    #pragma pack(pop)
    

    Das geht dann mit MSVC und GCC. (Keine Ahnung ob GCC auch die pshpack/poppack Headers hat, aber selbst wenn, Headers Inkludieren kostet Kompilierzeit -> lieber #pragma pack)

    @dot
    Gibt's eigentlich in der (neuen) Standard-Library binäre Serialisierungsfunktionen? Also sowas wie

    uint32_t read_uint32_le(void const*& ptr);
    

    Und/oder in der Boost?



  • @hustbaer: Nicht dass ich wüsste. Möglicherweise hat boost sowas, aber ich hab mich mit boost nie wirklich ernsthaft beschäftigt...


Anmelden zum Antworten