[C++] Bitmap Lade/Speicherroutine



  • Ich möchte mir eine Bitmap Lade/Speicherroutine schreiben.
    Nur ich weiß leider nicht, welche Datentypen ich dafür benutzen muss.
    Der Wikipediaeintrag hilft mir auch nicht wirklich weiter.

    class c_bitmap
    {
    private:
    
    	struct d_bitmap
    	{
    		struct d_bitmapHeader {
    			long		bitmapIdent;				// Enthält die Zeichenfolge 'BM'
    			short		bitmapSize;					// Größe der BMP-Datei in Byte. (unzuverlässig)
    			short		bitmapReserved;				// 0
    			short		bitmapOffbits;				// Offset der Bilddaten vom Beginn der Datei an (in Byte).
    		} header;									// Objekt für den Bitmapheader. Enthält grundlegende Bitmap-Informationen.
    
    		struct d_bitmapInfoheader {
    			short		bitmapSize;					// Größe des Informationsblocks in Byte.
    

    Sehr weit komme ich nicht, da die eingelesenen Werte nicht überall stimmen. 😡



  • #if !defined(BITMAP_H__INCLUDED)
    #define BITMAP_H__INCLUDED
    
    #include <string>
    
    class Bitmap
    {
    public:
    	Bitmap();
    	Bitmap(const std::string&);
    	~Bitmap();
    
    public:
    	void		load_bitmap(const std::string&);
    
    private:
        struct header
        {
    		unsigned short	wType;
    		unsigned long	dwSizeFile;
    		unsigned long	dwReserved;
    		unsigned long	dwOffset;
    		header() : wType(0), dwSizeFile(0), dwReserved(0), dwOffset(0)
    		{
    		}
    	}	m_header;
    	struct info
    	{
    		unsigned long	dwSize;
    		long			lWidth;
    		long			lHeight;
    		unsigned short	wPlanes;
    		unsigned short	wBpp;
    		unsigned long	dwCompression;
    		unsigned long	dwSizeFile;
    		long			lXPPM;
    		long			lYPPM;
    		unsigned long	dwBitColor;
    		unsigned long	dwImportantColors;
    		info () :	dwSize(0), lWidth(0), lHeight(0), wPlanes(0), wBpp(0), dwCompression(0), dwSizeFile(0),
    					lXPPM(0), lYPPM(0), dwBitColor(0), dwImportantColors(0)
    		{
    		}
    	}	m_info;
    };
    
    #endif // BITMAP_H__INCLUDED
    
    #include "Bitmap.h"
    #include <fstream>
    
    Bitmap::Bitmap()
    {
    }
    
    Bitmap::Bitmap(const std::string& filename)
    {
    	load_bitmap(filename);
    }
    
    Bitmap::~Bitmap()
    {
    }
    
    void Bitmap::load_bitmap(const std::string& filename)
    {
    	std::ifstream file_stream(filename.c_str(), std::ios::in|std::ios::binary);
    	if (!file_stream)
    		throw "Could not open file!";
    
    	file_stream.read(reinterpret_cast<char*>(&m_header), sizeof (Bitmap::header));
    	file_stream.read(reinterpret_cast<char*>(&m_info), sizeof (Bitmap::info));
    
    	// ... usw ... //
    }
    

    ... wo ist da die Schwierigkeit?



  • Naja ...

    Im folgenden bezeichnet WORD einen 16-Bit-vorzeichenlosen Integer, DWORD einen 32-Bit-vorzeichenlosen Integer und LONG einen im Zweierkomplement kodierten 32-Bit-Integer. BMP verwendet die Little Endian-Konvention.

    ...LONG einen im Zweierkomplement kodierten 32-Bit-Integer...

    Öhmm da hats geharkt 😉



  • So hab das Teil mal mit deinen Informationen fertiggestellt ...
    Aber das Bitmap wird immernochnicht richtig geladen 😡

    €dit:
    Warum gibt der mir mit sizeof ne Länge von 16 bytes aus, obwohl der Header nur 14 bytes lang sein darf ?!
    (MSVC++ 6.0 Pro)

    16 Bytes:

    struct d_bitmapHeader {
    			unsigned short		bitmapIdent;				// Enthält die Zeichenfolge 'BM'
    			unsigned long		bitmapSize;					// Größe der BMP-Datei in Byte. (unzuverlässig)
    			unsigned long		bitmapReserved;				// 0
    			unsigned long		bitmapOffbits;				// Offset der Bilddaten vom Beginn der Datei an (in Byte).
    		} header;
    

    16 Bytes:

    struct d_bitmapHeader {
    			unsigned char		bitmapIdent[2];				// Enthält die Zeichenfolge 'BM'
    			unsigned long		bitmapSize;					// Größe der BMP-Datei in Byte. (unzuverlässig)
    			unsigned long		bitmapReserved;				// 0
    			unsigned long		bitmapOffbits;				// Offset der Bilddaten vom Beginn der Datei an (in Byte).
    		} header;
    

    2 Bytes:

    struct d_bitmapHeader {
    			unsigned char		bitmapIdent[2];				// Enthält die Zeichenfolge 'BM'
    //			unsigned long		bitmapSize;					// Größe der BMP-Datei in Byte. (unzuverlässig)
    //			unsigned long		bitmapReserved;				// 0
    //			unsigned long		bitmapOffbits;				// Offset der Bilddaten vom Beginn der Datei an (in Byte).
    		} header;
    

    12 Bytes:

    struct d_bitmapHeader {
    //			unsigned char		bitmapIdent[2];				// Enthält die Zeichenfolge 'BM'
    			unsigned long		bitmapSize;					// Größe der BMP-Datei in Byte. (unzuverlässig)
    			unsigned long		bitmapReserved;				// 0
    			unsigned long		bitmapOffbits;				// Offset der Bilddaten vom Beginn der Datei an (in Byte).
    		} header;
    

    Sogar in beiden Varianten ( Sind wir nicht alle ein bisschen GAGA ?! )



  • Pyro Phoenix schrieb:

    €dit:
    Warum gibt der mir mit sizeof ne Länge von 16 bytes aus, obwohl der Header nur 14 bytes lang sein darf ?!

    Such mal nach "Padding" - der Compiler darf zwischen die struct-Elemente Füllbytes setzen, um sie an vernünftige Adressgrenzen ausrichten zu können.

    (der MSVC kennt eine #pragma Direktive, mit der du das ausschalten kannst)



  • Ich glaub, ich habs ...
    Für die Boardsuche:

    For Visual C++, you can disable padding as follows:

    #pragma pack(push)
    #pragma pack(1)
    struct Foo {
       ...
    };
    #pragma pack(pop)
    

    A better idea, though, is just to split the dword member into two words and be done with it. Your struct will generally be free of padding if each element is aligned to its size and the struct size is evenly divisible by the largest element.

    The rule for sizeof() is that it returns the size of an object as if it were an array element. Even though your struct doesn't need to be padded when used by itself, sizeof() still returns the padded size.


Anmelden zum Antworten