TGA lesen



  • Hi,

    ich schreib mir grad ne Funktion mit der ich den TGA Header auslesen kann. Aber irgendwas ist nicht ganz so wie es sein soll..

    damit lese ich den Header ein

    bool readTGAHeader( TGA_HEADER &header, char* filename ){
    
    	//std::ifstream file( filename, std::ios::binary | std::ios::in );
    	std::ifstream file( "blabla.tga", std::ios::binary | std::ios::in );
    	//check if opened correct
    	if( !file.is_open() ){
    		return false;
    	}
    
    	file.read( (char*)(&header), sizeof( header ) );
    
    	//was reading successful
    	if( file.bad() ){
    		file.close();
    		return false;
    	}
    
    	//close file
    	file.close();
    	return true;
    }
    

    das ist mein struct dazu

    typedef struct _TGA_HEADER
    {
    	char  identsize;          // size of ID field that follows 18 byte header (0 usually)
    	char  colourmaptype;      // type of colour map 0=none, 1=has palette
    	char  imagetype;          // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
    
    	short colourmapstart;     // first colour map entry in palette
    	short colourmaplength;    // number of colours in palette
    	char  colourmapbits;      // number of bits per palette entry 15,16,24,32
    
    	short xstart;             // image x origin
    	short ystart;             // image y origin
    	short width;              // image width in pixels
    	short height;             // image height in pixels
    	char  bits;               // image bits per pixel 8,16,24,32
    	char  descriptor;         // image descriptor bits (vh flip bits)
    
    	// pixel data follows header
    
    } TGA_HEADER;
    

    und damit gebe ich das wieder aus

    void printTGAHeader( TGA_HEADER &header ){
    
    	std::cout << "Size of Image-ID: " << (short)header.identsize << std::endl
    		<< "Type of Colourmap: " << (short)header.colourmaptype << std::endl
    		<< "Type of Image; " << (short)header.imagetype << std::endl
    		<< "Start of Colourmap: " << header.colourmapstart << std::endl
    		<< "Length of Colourmap: " << header.colourmaplength << std::endl
    		<< "Size of Colourmap Entry: " << (short)header.colourmapbits << std::endl
    		<< "X-Origin of Image: " << header.xstart << std::endl
    		<< "Y-Origin of Image: " << header.ystart << std::endl
    		<< "Width of Image: " << header.width << std::endl
    		<< "Height of Image: " << header.height << std::endl
    		<< "Bits per Pixel: " << (short)header.bits << std::endl
    		<< "vh-Flip bits: " << (short)header.descriptor << std::endl;	
    }
    

    wenn ich mir jetzt aber zb. den header einer tga ausgeben lasse bekomme ich sowas

    Size of Image-ID: 0
    Type of Colourmap: 0
    Type of Image; 2
    Start of Colourmap: 0
    Length of Colourmap: 0
    Size of Colourmap Entry: 0
    X-Origin of Image: 0
    Y-Origin of Image: 128
    Width of Image: 128
    Height of Image: 24
    Bits per Pixel: 0
    vh-Flip bits: 0
    

    wie ihr sehen könnt steht an der stelle Y-Origin die Größe des Bildes..also irgendwas spinnt da rum und ich steht hier grad auf dem schlauch...

    sieht einer von euch den fehler?
    danke euch schon mal.

    gruß



  • Du musst deinem Compiler mitteilen, dass er deinen TGA_HEADER nicht alignen soll.
    Wie das geht musst du mal in der Doku zu deinem Compiler nachschauen (such da einfach mal nach align oder alignment).



  • mmhh, kannst du mir das bitte kurz erklären? will auch verstehen warum ich was mache..

    habs noch nicht gefunden. ich nutze vs2005 also wenn wer schneller ist als ich, schiest los 🙂



  • Hi!

    #pragma pack( push, 1 )
    
    typedef struct _TGA_HEADER
    {
        char  identsize;          // size of ID field that follows 18 byte header (0 usually)
        char  colourmaptype;      // type of colour map 0=none, 1=has palette
        char  imagetype;          // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
    
        short colourmapstart;     // first colour map entry in palette
        short colourmaplength;    // number of colours in palette
        char  colourmapbits;      // number of bits per palette entry 15,16,24,32
    
        short xstart;             // image x origin
        short ystart;             // image y origin
        short width;              // image width in pixels
        short height;             // image height in pixels
        char  bits;               // image bits per pixel 8,16,24,32
        char  descriptor;         // image descriptor bits (vh flip bits)
    
        // pixel data follows header
    
    } TGA_HEADER;
    
    #pragma pack( pop )
    

    Du zwingst dem Compiler damit quasi die padding Bytes für das Alignment wegzulassen. Den unterschied siehst du wenn du sizeof( TGA_HEADER) einmal auf die gepackte und einmal auf die ungepackte Version anwendest!

    grüße



  • Schreib vor deinen Code

    #pragma pack(push, 1)
    

    und dahinter

    #pragma pack(pop)
    


  • also mit den pragmas klapt das wunderbar.

    nun bin ich aber neugierig geworden..kann mir einer erklären was es mit dem alignment auf sich hat?

    und was genau macht pack() dabei genau?

    danke euch schonmal für die hilfe



  • Ohne das "pack" richtet der Compiler die einzelnen struct-Member so aus, dass der Prozessor optimal auf sie zugreifen kann (bei 32-Bit-Prozessoren so, dass sie an 4-Byte-Grenzen liegen).

    Beispiel:

    struct test
    {
        char a;
        int b;
        char c;
        int d;
    };
    
    printf("%d\n", sizeof(test));
    

    Bei mir kommt da 16 raus, obwohl 1+4+1+4 doch 10 ist.
    Hier sieht man, dass der Compiler nach dem "a" und dem "c" noch drei "Padding-Bytes" einfügt.
    Im Speicher sieht das ganze dann so aus:

    a
    PADDING
    PADDING
    PADDING
    b
    b
    b
    b
    c
    PADDING
    PADDING
    PADDING
    d
    d
    d
    d
    

    Mit pack(1) richtet der Compiler die Members an 1-Byte-Grenzen aus, fügt also keine Padding-Bytes ein.



  • bin bei meiner sucherei auf das hier gestoßen..ggf. interessiert es noch wen...
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_predir_pragma_directives.asp

    danke nochmal an alle, habs nun geblickt und weiß was ich tue



  • [b]cute[b]

    Hier stand mal ein schwachsinn meiner muedigkeit.



  • Char entspricht einem Byte. Die Größe eines Bytes ist allerdings nicht festgelegt, du kannst hier aber von 8 Bit ausgehen. D.h. ein Char entspricht in diesem Fall 8 Bit.
    D.h. es hat einen Maximalwert von 0xff (wenn unsigned) oder 0x7f (wenn signed).
    0xffff sind übrigens 16 bit: 1111 1111 1111 1111 im Binärsystem.
    Und ein boolean belegt auf jedenfall mehr als ein Bit!

    grüße



  • Jetzt wo wir schon mal bei TGAs sind:
    Ich hab die eine Funktion von den Nehe-Tutorials zum TGA-Laden, aber wenn ich mit IrfanView Bilder Im TGA-Format abspeichere kann die Ladefunktion die Bilder nicht laden, obwohl die Bilder unkomprimiert abgespeichert sind.
    Tja, Problem.
    Wisst ihr vielleicht was?



  • oh shit, ich hab's vergeben.
    stimmt... keine ahnung was ich mir gedacht habe...



  • David_pb schrieb:

    Char entspricht einem Byte. Die Größe eines Bytes ist allerdings nicht festgelegt

    Umgekehrt!



  • TomasRiker schrieb:

    David_pb schrieb:

    Char entspricht einem Byte. Die Größe eines Bytes ist allerdings nicht festgelegt

    Umgekehrt!

    keins von beiden 😛



  • Hi!

    Was redest du da TomasRiker?

    Byte
    Die Größe ist nicht unbedingt 8 Bit, es muss nur:
    ➡ groß genug sein, um jedes Element des Basisausführungszeichensatzes speichern zu können
    ➡ aus einer Folge hintereinander liegender Bits bestehen und
    ➡ Adressierbar sein

    Char
    Die Größe eines Char ist ein Byte
    ➡ sizeof() liefert die Größe eines Types in Byte
    ➡ sizeof( char ) liefert immer 1

    grüße



  • Das war mir gar nicht bewusst.
    Allerdings gibt der Wikipedia-Artikel mehrere Definitionen an.
    Am besten sagt man dann wohl "Oktett", wenn man 8 Bits meint 😉



  • ich hab irgendwo auch noch eine andere definition von byte als die kleinste einzeln adressierbare einheit des systems gefunden...

    dass sizeof(char) immer 1 liefert steht scheinbar im C standard, obs bei C++ auch so ist, weis ich nicht.



  • dot schrieb:

    ich hab irgendwo auch noch eine andere definition von byte als die kleinste einzeln adressierbare einheit des systems gefunden...

    dass sizeof(char) immer 1 liefert steht scheinbar im C standard, obs bei C++ auch so ist, weis ich nicht.

    In C++ ist das genauso festgelegt. Weil ein Char immer einem Byte entspricht.

    grüße



  • David_pb hat recht, was er sagt steht auch so im (C++)Standard.

    Die Zahl der Bits in einem char kann man übrigens mit std::numeric_limits< unsigned char >::digits abfragen (steht in <limits>).
    Dies ist im Übrigen keine universelle Möglichkeit für jeden built-in Typ die Anzahl an Bits abzufragen:

    msdn schrieb:

    The member stores the number of radix digits that the type can represent without change, which is the number of bits other than any sign bit for a predefined integer type, or the number of mantissa digits for a predefined floating-point type.



  • @simmon

    hast du dir mal den header in einem hex editor angeguckt? ggf. gibt das in verbindung mit deinem source code auschluss was schief läuft


Anmelden zum Antworten