Sucher Unterschied in zwei Aufgabengleichen Codes



  • Hallo, nachdem ich erfolglos versuchte ein bestimmtes Bildformat zu laden(welches spielt hier denke ich eine Rolle) schrieb ich den code nochmal von vorne und nun funktioniert er wundersamerweise, wobei mir nicht klar ist, an welcher stelle ich etwas verschieden mache.
    Hier die entscheidenen Stellen der Codes:

    Der richtige:

    ifstream in("kfm720.sff",ios::in |ios::binary);
    
        sff2header head;
        spriteheader sprite;
    
        in.read((char*)&head,sizeof(sff2header));
        in.seekg(head.spriteoffset);
        in.read((char*)&sprite,sizeof(spriteheader));
    
        if(sprite.flags == 0)
        in.seekg(sprite.dataoffset + head.literaloffset);
        else
        in.seekg(sprite.dataoffset + head.translationoffset);
    
        unsigned int length;
        in.read((char*)&length,sizeof(unsigned int));
        char* data = new char[sprite.width*sprite.height];
    
        if(sprite.encryp == 2)//decode special RLE8
        {
            unsigned int index = 0;
            while(index < (sprite.width * sprite.height))
            {
                unsigned char byte = in.get();
                if((byte & 0xC0) == 0x40)
                {
                  unsigned char color = in.get();
                  for(int i = 0; i<(byte& 0x3F);i++)
                  {
                     data[index] = color;
                     index++;
                  }
                }
                else
                {
                    data[index] = byte;
                    index++;
                }
            }
        }
    
        palheader palhead;
    
        in.seekg(head.paletteoffset);
        in.ignore((sprite.palindex)*sizeof(palheader));
        in.read((char*)&palhead,sizeof(palheader));
    
        in.seekg(palhead.literaloffset + head.literaloffset);
        RGB* pal = new RGB[palhead.numcols];
        cout << palhead.numcols << endl;
        for(int i = 0; i < palhead.numcols;i++)
        {
            pal[i].r = ((unsigned char)in.get())/4;
            pal[i].g = ((unsigned char)in.get())/4;
            pal[i].b = ((unsigned char)in.get())/4;
            in.ignore();
        }
        BITMAP* image = create_bitmap_ex(8, sprite.width, sprite.height);
        unsigned int j = 0;
        for(int h = 0; h <sprite.width;h++)
            for(int w = 0;w < sprite.height;w++)
            {
                image -> line[h][w] = data[j];
                j++;
            }
            set_palette(pal);
            draw_sprite(screen,image,100,100);
    

    Nun der falsche, ich denke mein Fehler liegt bei der Verwendung von der vectorklasse:

    ifstream myfile("kfm720.sff",ios::in | ios::binary);
        myfile.read((char*)head,sizeof(sff2header));
        vector<spriteheader*> spritenodes(head -> countsprites,new spriteheader);
        vector<char*> data;
        vector<palheader*> palhead(head -> numpalettes,new palheader);
        myfile.seekg(head -> spriteoffset);
    
        for(int i = 0;i <1;i++)//Ich lese testweise nur ein Bild aus
        {
    
            myfile.read((char*)spritenodes[i],sizeof(spriteheader));
    
            unsigned int size = (spritenodes[i] -> width) * (spritenodes[i] -> height);
            unsigned int index = 0;
    
            if(spritenodes[i] -> spritelength != 0)
            {
                data.push_back(new char[size]);
                remember = myfile.tellg();
                if(spritenodes[i] -> flags == 0)
                myfile.seekg((head -> literaloffset)+(spritenodes[i] -> dataoffset));
                else
                myfile.seekg((head -> translationoffset)+(spritenodes[i] -> dataoffset));
    
                unsigned int length;
                myfile.read((char*)&length,sizeof(unsigned int));
    
                if(spritenodes[i] -> encryp == 2)//RLE 8
                {
    
                    while(index < size)
                    {
    
                        unsigned char c = myfile.get();
    
                        if((c & 0xC0) == 0x40)
                        {
                            unsigned char colour = myfile.get();
    
                            for(int k =  0; k < (c&(0x3F));k++)
                            {
                               data[i][index] = colour;
                               index++;
                            }
    
                        }
                        else
                        {
    
                            data[i][index] = c;
                            index++;
    
                        }
                     }
    
                }
    }
            else
            {
                data.push_back(NULL);
            }
    
            myfile.seekg(remember);
    
    }
    
    myfile.seekg(head -> paletteoffset);
    
    for(int i = 0;i < head->numpalettes;i++)
    myfile.read((char*)palhead[i],sizeof(palheader));
    
    myfile.seekg((head -> literaloffset)+(palhead[6] -> literaloffset));
    RGB* pal = new RGB[palhead[6] -> numcols];//[palhead[5] -> numcols];
    textout(palhead[6]->numcols,20,10);
    
    for(int i = 0;i<palhead[6] -> numcols;i++)
    {
        pal[i].r = ((unsigned char)myfile.get())/4;
        pal[i].g = ((unsigned char)myfile.get())/4;
        pal[i].b = ((unsigned char)myfile.get())/4;
        myfile.ignore();
    }
    
    BITMAP* toshow = create_bitmap_ex(8, spritenodes[0] -> width, spritenodes[0] -> height);
    unsigned int j = 0;
    for(int k = 0;k < spritenodes[0] -> height;k++)
        for(int u = 0; u < spritenodes[0] -> width;u++)
        {
            toshow -> line[k][u] = data[0][j];
            j++;
        }
    
    set_palette(pal);
    draw_sprite(screen,toshow,100,100);
    

    Habe ich beim laden in die Vektoren etwas falsch gemacht/falsch verstanden? Denn mir ist keine mögliche andere Fehlerquelle bewusst.
    Sind die Codes nicht bedeutungsgleich?

    Ich hoffe die Codes sind für Fremde lesbar:/

    Ferner ist der Code noch nicht in eine Klasse eingebettet, da ich ihn erst "nackt" testen wollte, bitte das erstmal nicht kritisieren



  • Ich habe nicht alles nachvollzogen, aber ich würde mal als erstes alle C-Casts durch C++ Casts ersetzen, dann wirst du schon mal vom Compiler ein paar Hinweise bekommen.

    myfile.read((char*)spritenodes[i],sizeof(spriteheader));
    

    Ich weiß nicht was ein spriteheader ist, aber das sieht schonmal ziemlich daneben aus.
    Dann würde ich die ganzen new s rausschmeißen. Ich sehe keins, dass notwendig ist.
    Und um Abtwort auf deine eigentlich Frage zu finden, würde ich beide Versionen mal mit einem Debugger durcheghen. Da sollte dir schnell klar werden was los ist.



  • vielen dank für deine antwort.

    myfile.read((char*)spritenodes[i],sizeof(spriteheader));
    

    spritenodes ist ein vector von zeigern auf spriteheader, welches eine struktur ist.
    wird zwar soweit ich weiß immer empfohlen struturen elementweise einzulesen, allerdings weiß ich nicht wieso, da diese variante fehlerlos funktioniert

    wieso die ganzen news rausschmeißen? Meinst du ich sollte das lieber mit Push_back() machen?

    Debugger funktioniert leider nicht, da es da Probleme mit Allegro(die Grafikbibliothe die ich benutze) und meinem debugger gibt.



  • kingcools2 schrieb:

    allerdings weiß ich nicht wieso, da diese variante fehlerlos funktioniert

    Dass etwas mal zufällig fehlerfrei funktioniert, ist kein Grund anzunmehmen, dass es es ein guter Weg ist.

    kingcools2 schrieb:

    wieso die ganzen news rausschmeißen? Meinst du ich sollte das lieber mit Push_back() machen?

    Wieso z.b. vector<spriteheader*> und nicht vector<spriteheader>. Wieso char* data und nicht std::vector<char> oder std::string?

    kingcools2 schrieb:

    Debugger funktioniert leider nicht, da es da Probleme mit Allegro(die Grafikbibliothe die ich benutze) und meinem debugger gibt.

    Ein Debugger ist fast so wichtig wie der Texteditor. Bevor du über irgendetwas anderes nachdenkst solltest du den zum Laufen bringen.



  • Hallo, ich habe nun die vectoren abgeändert in vectoren ohne zeigern als elemente sondern mit echten variablen bzw hier strukturen.
    Das hat tatsächlich mein Problem behoben.
    Allerdings verstehe ich nicht wieso.

    Also folgendes:

    Habe

    vector<palheader*> palhead(head -> numpalettes,new palheader);
    

    in:

    vector<palheader> palhead(head -> numpalettes);
    

    geändert und weiter unten:

    for(int i = 0;i < head->numpalettes;i++)
    myfile.read((char*)&palhead[i],sizeof(palheader));
    

    also schlicht das "&" hinzugefügt. Danach natürlich alle "->" durch Punkte.
    Dann ging es.

    Die Frage ist wieso? Was funktioniert jetzt nicht genauso wie vorher?

    Wie ich mir das vorgestellt hatte:
    palhead war ein vector mit zeigern auf palheader.
    Dieser Vector wurde deklariert mit allokiertem Speicher allerdings ohne die Werte zu initialisieren. Dies wurde später getan über eben myfile.read(...)
    Hierbei wurde der Zeiger palhead[i] "umgedeutet" als Zeiger auf char* und dann so viele bytes, an der Stelle an die besagter zeiger zeigt, eingelesen wie die palheader struktur lang ist(in byte).

    kann es sein, dass

    (char*)palhead[i]
    

    als palhead noch zeiger als elemente hatte, nicht auf das erste Byte von dem allokierten Speicher gezeigt hat? Das kann doch eigentlich nicht sein, oder hätte der Compiler dann keinen Fehler gemeldet?


Log in to reply