Datein einlesen...
-
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.
-
@CStoll, ist mir auf den ersten Blick auch nicht ganz klar das Code, denke aber dass ich mich da durch tüffteln könnte mit googel
Templates kann ich sowieso nicht immer ausweichen, steht schon auf meiner ToDo Liste.Ja super fein, diese ints muß ich ja gleich einmal ausprobieren. Aber wo kann ich mir den Standard ansehen? Oder wo siehst du da nach, weil ich habe auf die schnelle eher unübersichtliche Docs gefunden, muß aber noch genauer sehen.
lg Darian
-
Darian schrieb:
@CStoll, ist mir auf den ersten Blick auch nicht ganz klar das Code, denke aber dass ich mich da durch tüffteln könnte mit googel
Templates kann ich sowieso nicht immer ausweichen, steht schon auf meiner ToDo Liste.Das Ding dort oben simuliert einen 2 Byte großen Ganzzahltyp - für Systeme, auf denen selbst short zu groß sein sollte. Auf gängigen Systemen dürfte aber ein
tyedef short word;völlig ausreichen.
-
Das freut mich dass es ausreichend ist.
Habe ein Testbild gemacht mit 10 Pixel, und fixen Farbwerten, aber es ging nicht, und die Farbwerte passen nicht so ganz.
Erste Pixel rot:
Pixel1: 255
Pixel2: 0
Pixel3: 0
...usw (bis erst einmal 10 Werte die es mir ausgibt)Ist aber ganz was anderes...
Kann mir da jemand sagen woran das liegt, weil das selbe habe ich ja mit dem Bitmap auch gehabt, und ist jetzt bei dem tga Loader das selbe.
Wenn ich das gelöst habe, könnte ich weiter kommen.
Wäre super wenn mir hier jemand Infos geben kann!
lg Darian
-
Schau dir doch auch mal an, mit welcher Bitgröße dein Bild gespeichert ist - das kann zwischen 1 und 32 Bit pro Pixel liegen und macht durchaus Unterschiede bei der Repräsentation der Farbwerte.
(1- bis 8-Bit-Bilder verwenden eine Farbtabelle, in der für jede Bitkombination eine RGB-Kombination steht, größere Bilder speichern die Farben direkt (bei 32 Bit je ein Byte R,G,B und ungenutzt))
-
Hallo,
jedes Pixel ist mit 24 Bit gespeichert also ganz normal RGB oder in einer anderen Reihenfolge, weiß ich jetzt nicht genau.
Ich dachte nachdem es keine Farbpalette gibt, und Bild-ID optional ist, und auch nicht da ist (glaube ich zumindest) beginnen gleich nach dem Header die Bildaten.
Aber ich komme auf keine brauchbaren Werte.
Der Code hat sich bis jetzt zu dem obigen noch nicht verändert.
lg
-
Darian schrieb:
jedes Pixel ist mit 24 Bit gespeichert also ganz normal RGB oder in einer anderen Reihenfolge, weiß ich jetzt nicht genau.
Ist das eine Vermutung von dir oder hast du das im Header (Feld biBitCount) kontrolliert? (achja, die Reihenfolge ist BGR)
Ich dachte nachdem es keine Farbpalette gibt, und Bild-ID optional ist, und auch nicht da ist (glaube ich zumindest) beginnen gleich nach dem Header die Bildaten.
Was zwischen Header und Bilddaten liegt, hängt vom Programm ab, das die Datei geschrieben hat - jedenfalls solltest du dich nicht darauf verlassen, daß die lückenlos aufeinander folgen. Darum gibt es auch den Eintrag bfOffBits - der sagt dir, wo die Bilddaten beginnen.