Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

31.05.2011, 19:10

PNG Loader

Hallo,

nach ein wenig Spaß mit 2D und TGA Texturen, will ich jetzt zu Übungszwecken einen PNG Loader schreiben. Doch ich habe jetzt schon beim laden des IHDR Headers ein Problem:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// pngFile.h

struct pngHeader{
    int width;
    int height;
    char depth;         // Bittiefe 1, 2, 4, 8, 16
    char color_type;    // Farbtyp 0, 2, 3, 4, 6
    char comp;          // compression 0
    char filter;        // 0
    char interlace;     // 0,1
};

class pngFile{
    private:
        pngHeader m_header;

    public:
        pngFile();
        bool load(string path);
};

// pngFile.cpp

bool pngFile::load(string path){
    ifstream file(path.c_str(), ios::binary);

    if(!file.good()){
        cerr<<"Could not open the PNG image file!"<<endl;
        return false;
    }

    // Header
    file.seekg(16);
    file.read(reinterpret_cast<char*>(&m_header.width), sizeof(int));
        
    return true;
};


Wenn ich mir jetzt z.B. die Breite des Bildes ausgeben lassen will (64) steht diese nicht da, sondern 84 oder so. Wenn ich die ersten 100 Bytes mit einer for durchlaufe stehen dort aber die Daten so wie im Header hintereinander. sizeof(pngHeader) gibt mir auch 16 statt 13?!

Guckt euch den Code mal an, ich weiß nicht woran das liegt. Für mich ist int+int+5*char = 13 Bytes und nicht 16...

MfG DK

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

31.05.2011, 19:39

sizeof(pngHeader) gibt mir auch 16 statt 13?!

Guckt euch den Code mal an, ich weiß nicht woran das liegt. Für mich ist int+int+5*char = 13 Bytes und nicht 16...

Schau dir mal an was struct padding ist...

Ansonsten: Das PNG Format ist Chunkbasiert, Header auslesen funktioniert vielleicht noch so aber wenn du wirklich das PNG laden willst wirst du mit den Chunks arbeiten müssen. PNG speichert Integer als Big-Endian, d.h. auf x86 wirst du die Reihenfolge der Bytes umdrehen müssen um die richtigen Werte zu bekommen. Abgesehen von all dem hoffe ich dass dir klar ist dass PNG ein komprimiertes Format ist, d.h. einfach mal die Bilddaten auslesen is nicht, du wirst die entsprechenden Algorithmen entweder selber implementieren oder eine Bibliothek verwenden müssen die das für dich tut. PNG zu laden ist nicht wirklich was was ich jemanden so zum Spaß empfehlen würde. Wenn du PNG support brauchst verwend eine Library dafür. Wenn du jetzt trotzdem weitermachen willst: Die komplette Spezifikation des Dateiformats findest du z.B. hier.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (31.05.2011, 19:45)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

4

31.05.2011, 19:45

Ok:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct pngHeader{
    unsigned char width[4];
    unsigned char height[4];
    unsigned char depth;            // Bittiefe 1, 2, 4, 8, 16
    unsigned char color_type;   // Farbtyp 0, 2, 3, 4, 6
    unsigned char comp;         // compression 0
    unsigned char filter;       // 0
    unsigned char interlace;        // 0,1
};

// Header lesen
    file.seekg(16);
    file.read(reinterpret_cast<char*>(&m_header.width), sizeof(pngHeader));
        
    cout<<int(m_header.width[3])<<endl;     // = 64 Passt!
    cout<<int(m_header.height[3])<<endl;    // = 128 Passt auch!


Aber das ist doch total hässlich... Warum kann ich die Werte nicht direkt in ein int mit 4 Bytes lesen?

[EDIT]

Ich wollte das vor allem machen da meine TGA keinen Alphakanal speichern, obwohl ich das bei GIMP und Photoshop so eingestellt habe. Der Loader kanns nicht sein da auch Ifran und was weiß ich das falsch anzeigen. Das PNG vielleicht nicht das einfachste Format ist weiß ich.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

31.05.2011, 19:47

Aber das ist doch total hässlich... Warum kann ich die Werte nicht direkt in ein int mit 4 Bytes lesen?

Hast du gelesen was ich geschrieben hab? Du musst eben die Byte-Order berücksichtigen. Verwend z.B. nothl() oder mach dir selbst was...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

31.05.2011, 19:51

Ich wollte das vor allem machen da meine TGA keinen Alphakanal speichern, obwohl ich das bei GIMP und Photoshop so eingestellt habe.

Dann würd ich eher mal versuchen das zu fixen oder zumindest libpng verwenden anstatt PNG selber zu implementieren. Aber ist natürlich deine Entscheidung.

Das PNG vielleicht nicht das einfachste Format ist weiß ich.

Ok, in meinem vorletzten Post steht dann ja schon alles was du so brauchen wirst...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

7

31.05.2011, 19:52

Ich hab das geschrieben bevor ich aktuallisiert hab :)
Mit dem PNG mach ich jetzt solange weiter bis ich kein Bock mehr hab. Dann hol ich mir nen fertigen Loader :P
Mir geht es hauptsächlich darum selber Dateiformate auslesen und beschneiden zu können. Nur MD2 und TGA wie im Buch ist ein wenig langweilig.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

8

31.05.2011, 19:53

Zitat


Zitat von »DeKugelschieber«
Ich wollte das vor allem machen da meine TGA keinen Alphakanal speichern, obwohl ich das bei GIMP und Photoshop so eingestellt habe.

Dann würd ich eher mal versuchen das zu fixen oder zumindest libpng verwenden anstatt PNG selber zu implementieren. Aber ist natürlich deine Entscheidung.


Da steht TGA nicht PNG :)

[EDIT]

Ach sorry so meinst du das.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

31.05.2011, 19:54

Dann such dir doch was einfacheres. Ich würd z.B. DDS empfehlen oder einfach bmp...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

31.05.2011, 19:55

Irgendwer muss ja sowas wie pnglib schreiben oder?

Werbeanzeige