Datein einlesen...



  • Mah stimmt, so ist es richtig, jetzt hat es funktioniert, und sogar die richtige Breite wurde ausgegeben.

    Nachdem das jetzt passt, kann ich mal gemütlich versuchen das alles dementsprechend zu verarbeiten. Jetzt wo ich die Basics habe.

    lg und danke für diesen Tipp, habe ich wohl übersehen
    Darian



  • Habe jetzt einmal den Header eingelesen, und stehe jetzt bei dem auslesen der ersten Pixel, da scheint es irgendwie wieder weniger zusammen zu passen.

    Muß ich jetzt ersteinmal die Farbpalette in einen Array laden?

    Hier er Code:
    http://nopaste.info/94d173b2b5.html

    Wäre super wenn ich noch ein paar Infos kriege.
    Ach ja, hätte ich den Header auch irgendwie mit einer Schleife laden können, anstatt alles manuell aus zu schreiben?? (mir ist da irgendwie nichts eingefallen!)

    lg
    Darian



  • Darian schrieb:

    Habe jetzt einmal den Header eingelesen, und stehe jetzt bei dem auslesen der ersten Pixel, da scheint es irgendwie wieder weniger zusammen zu passen.

    Muß ich jetzt ersteinmal die Farbpalette in einen Array laden?

    Wenn das Bild eine Farbepalette hat, vermutlich ja. Andernfalls kann es sein, daß zwischen Header und Bilddaten noch Müll steht - im Header steht auch drin, wo die Nutzdaten beginnen.



  • Ach ja, hätte ich den Header auch irgendwie mit einer Schleife laden können, anstatt alles manuell aus zu schreiben?? (mir ist da irgendwie nichts eingefallen!)

    hättest auch ne struct machen können die genau die selben variablen mit selber größe hat und da alles auf einmal reinkopieren.



  • Hallo,

    ja habe ich sogar, aber wie hätte ich das aufeinmal rüber kopieren können?

    struct Bitmap_Header
     {
         // BITMAPFILEHEADER
         word bfType;
         dword bfSize;
         dword bfReserved;
         dword bfOffBits;
    
         //BITMAPINFOHEADER
         dword biSize;
         long biWidth;
         long biHeight;
         word biPlanes;
         word biBitCount;
         dword biCompression;
         dword biSizeImage;
         long biXPelsPerMeter;
         long biYPelsPerMeter;
         dword biClrUsed;
         dword biClrImportant;
     };
    

    Wäre interessant, damit ich es das nächste mal brauchbarer mache, und es nicht wieder soviel Arbeit für mich ist.

    lg Darian



  • na, so wie du breite und höhe eingelesen hast nur mit struct adresse und sizeof Bitmap_Header



  • Hallo, habe das jetzt probiert, gibt dann aber nicht das richtig aus!

    Meinst du so:

    heightmap.seekg(0, ios::beg);
    heightmap.read(reinterpret_cast<char*>(&header), sizeof(Bitmap_Header));

    Stimmt das so??

    Na ja, das wäre doch sehr interessant für mich für die Zukunft, also bitte noch um die nötigen Infos für das praktische einlesen.

    lg Darian



  • Wenn die struct aus PODs besteht, kannst du durch:

    file_stream.read(reinterpret_cast<char*>(&my_struct), sizeof(my_struct));
    

    die Daten einlesen, jap. Ehm dabei musst du aber einiges beachten. Das zu erklären, überlasse ich anderen, weil ich jetzt in die Haia gehe :xmas1:



  • Na ja, habe ich eh so gemacht, oder meinst du es anders?

    Aber es werden wenn ich zum Beispiel die Höhe Ausgeben will, nur komische zahlen ausgegeben, aber nicht die, die es sein sollten.

    Wäre echt super wenn mir das noch jemand erklären könnte.

    lg Darian



  • (D)Evil schrieb:

    Ehm dabei musst du aber einiges beachten. Das zu erklären, überlasse ich anderen, weil ich jetzt in die Haia gehe :xmas1:

    Das wichtigste, was du dabei beachten solltest ist, daß die verwendete Struktur "dicht" im Speicher steht - d.h. du solltest das Padding ausschalten (frag mal deine Compiler-Doku, wie das geht). Sonst landen einige der Nutzdaten in den Füllbytes, mit denen der Compiler dafür sorgt, daß die Elemente an vernünftigen Speicheradressen ausgerichtet werden.

    Und du solltest dich bei den Datentypen nicht auf die Built-ins verlassen - deren exakte Größe ist nämlich nicht standardisiert (nur Mindestgrößen).



  • Na ja, nachdem man da extra wieder beim Compiler herum stellen muß, wäre es wohl besser man codet es doch gleich aus? Oder wie wird das sonst so gemacht?

    Das mit dem padding muß ich mir wirklich dann mal genauer durchlesen benutzte übrigends g++ unter Linux.

    Sorry, aber was meinst du mit Built-ins?

    lg
    Darian



  • Darian schrieb:

    Sorry, aber was meinst du mit Built-ins?

    Die eingebauten Datentypen von C++ - char, short, int etc. Wenn du mit WORD und DWORD arbeitest, kannst du mit einigen Präprozessor-Einstellungen oder Templates sicherstellen, daß diese IMMER die erforderliche Größe haben.

    PS: Und das typische Vorgehen ist tatsächlich, dort für die Strukturen das Padding auszuschalten (nicht unbedingt für's gesamte Programm). Unter VC sieht das z.B. so aus:

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


  • Hallo,

    ich dachte dass int und short auf einem 32Bit CPU immer gleich viel haben.
    und daher mit folgendem Code, müßten word und dword auch die selben haben. (dachte ich bis jetzt zumindest so)

    //Define Datatypes
    typedef unsigned short int word;
    typedef unsigned int dword;

    Bezügich padding habe ich jetzt im manual von g++ nichts gefunden. Ich konnte nur raus lesen dass ein paar Sachen nicht kompatibel sind mit anderen, und was falsch ist zu machen. Aber wie man padding selbst macht, stand nicht da. (und natürlich auch dass die binarys möglicherweise mit binarys von anderen Compilern nicht kompatibel sind)

    Werde wohl mal genauer suchen, oder irgendwo nachfragen müßen...

    lg und danke für die Infos
    Darian



  • Darian schrieb:

    Hallo,

    ich dachte dass int und short auf einem 32Bit CPU immer gleich viel haben.
    und daher mit folgendem Code, müßten word und dword auch die selben haben. (dachte ich bis jetzt zumindest so)

    Der Ansi Standard legt nur fest, daß beide Typen mindestens 16 Bit groß sein müssen - nach oben ist das keine Grenze vorgeschrieben. Deine Probleme werden vermutlich dann beginnen, wenn ein Compiler anderer Meinung ist als dein aktueller (mit typedef reicht es, das an einer Stelle zu korrigieren, wenn du int direkt verwendet hast, mußt du den gesamten Code danach absuchen).



  • Ahh jetzt ist es klar.

    Es dann vermutlich besser für mich wenn ich mir zu Beginn eines größeren Projektes alles Datentype so selbst definiere, damit man es leicht ändern kann bei Problemen.

    Jetzt ist mir auch klar warum es bei OpenGL lauter eigene Datentypen gibt GLint GLuint...usw. d.h. für mich ich sollte in Zukunft doch die OpenGL Datentypen verwenden, ist dann wohl logischerweise besser.

    Ja das long dass ich verwendet habe ist ja auch nicht selbst definiert, sollte ich eigentlich dann auch so machen...

    Danke, war sehr informativ, und mir ist ein Licht aufgegangen.

    Jetzt wäre nur noch interessant wie ich das mit dem padding überprüfen kann, weil dann kann ich herum probieren.

    Wie kann ich checken ob padding on oder off ist?

    lg Darian



  • Hallo Leute,

    das mit dem Padding funktioniert jetzt schon, mir ist zwar noch immer nicht so klar wie das gemeint ist, oder wie das alles im Hintergrund genau arbeitet, aber es geht zumindest.

    http://nopaste.info/59bec70c84.html

    Jetzt sollte ich mir noch eine Art long Ersatz machen, dass man es leicht ändern kann falls ein long mal nicht die 4 Byte hat..oder?

    Oder wie würdet ihr da vor gehen um diese eine Fehlerquelle jetzt noch auszuschalten?

    lg Darian

    Edit: Wie sind jetzt die Farbtabellen auszulesen:...

    unsigned char pixel1;
    heightmap.seekg(54, ios::beg);
    heightmap.read(reinterpret_cast<char*>(&pixel1), sizeof(unsigned char));
    cout << pixel1 <<endl;
    

    Gibt nur folgendes aus: "Pixel1: " also gar nichts...



  • Darian schrieb:

    Jetzt sollte ich mir noch eine Art long Ersatz machen, dass man es leicht ändern kann falls ein long mal nicht die 4 Byte hat..oder?

    Bei Windows ist WORD==2 Byte, DWORD==4 Byte, also nimm doch letzteres.

    (PS: Und weiter oben hatte ich einen Link zur FAQ gepostet, wo die Typ-Bestimmung für feste Größen über Templates gelöst ist)



  • @CStoll, ich bin im Linux unterwegs und habe daher kein dword oder so glaub ich zumindest.

    Das mit den Templates ist mir leider noch zu hoch, daher würde ich es gerne ohne machen. Aber ich werde mir das noch genauer ansehen um endlich einmal über die, ahhh bitte keine Templates, Phase weg zu kommen.
    (werde mal ein paar Dokus darüber lesen müßen)

    lg Darian



  • Darian schrieb:

    @CStoll, ich bin im Linux unterwegs und habe daher kein dword oder so glaub ich zumindest.

    Und trotzdem verwendest du es in deinem struct 😃

    PS: Wenn du nicht mit Templates arbeiten willst, kannst du auch den Präprozessor bemühen - ist allerdings etwas aufwendiger, für jeden in Frage kommenden Compiler einen 2-Byte- (word) und einen 4-Byte- (dword) Datentyp zu suchen.

    PS: Auf den meisten Systemen sollte word==short und dword==int ausreichend sein. Und wenn tatsächlich jemand einen zu großen short definiert, müsstest du dir doch selber etwas basteln:

    //achtung - ungetestet
    class word
    {
      char data[2];
    public:
      word(short val)
      {
        data[0]=(val>>8)&0xFF;
        data[1]=val&0xFF;
      }
      operator short()
      {
        return data[0]<<8 | data[1]&0xFF;
      }
    };
    


  • Unter Linux stehen Dir aber Typen wie int8_t, int16_t, uint8_t usw. zur Verfügung. Diese Typen sind auch im aktuellen Standard erwähnt, jedoch optional, müssen also nicht zwingend vorhanden sein.


Anmelden zum Antworten