C++ Datenzugriff auf Binärdateien

Eyken

Cadet 1st Year
Registriert
März 2013
Beiträge
8
Hallo,

Eine Binärdatei (Dat.cis) enthält ("Reihe für "Reihe", erster Punkt liegt oben links, letzter unten rechts) Informationen über eine Messung. Das Gerät hat mehrere Messwerte für jeden Pixel aufgenommen. Jeder Pixel entspricht einer Instanz der Struktur:

typedef struct{
short az, co;
char ao[8];
short nm;
char rq;
char gq;
} dataStruct;

Ich möchte daraus ein Bild generieren welches nur die Informationen eines Messwertes (z.B. az) enthält.

Die Binärdatei wird folgendermaßen eingelesen:

void * mData = malloc(mWidth*mHeight*sizeof(dataStruct));
FILE* fp=fopen("data.cis", "rb");
size_t count=fread(mData,sizeof(dataStruct),mWidth*mHeight, fp);
fclose(fp);
free(mData);

Diese Quellcode stammt vom Hersteller (daher auch der teilweise C-Stil), ich habe nur die fehlenden Typen (void, FILE, size_t) ergänzt (richtig?).

Um ein Bild zu generien muss ich auf jeden einzelnen Pixel für z.B. az zugreifen können.

Prinziell würde ich so vorgehen:

dataStruct *p;
short d;
d=p[1].az;

Dies funktioniert natürlich nicht, da der Zeiger p nicht initialisiert wird. Leider weiß ich nicht wie ich dies anstellen soll.

Ist der prinzipielle Weg richtig, wenn ja, wie intitialisiere ich p? Falls nicht, wie kann ich vorgehen?
 
Danke schonmal! Also mein Quelltext lautet jetzt:


typedef struct{
short az, co;
char ao[8];
short nm;
char rq;
char gq;
} dataStruct;

int mWidth = 6720;
int mHeight = 3360;


void * mData = malloc(mWidth*mHeight*sizeof(dataStruct));
FILE* fp=fopen("data.cis", "rb");
size_t count=fread(mData,sizeof(dataStruct),mWidth*mHeight, fp);
fclose(fp);




dataStruct *p = (dataStruct *)mData;
short d;
d=p[1].az;
cout<<d;


free(mData);

Also ich bekomme Werte ausgegeben, ob diese auch wirklich korrekt sind, werde ich aber erst erfahren, wenn ich mich etwas weiter in OpenCV eingelesen habe .

Noch was: Wie lässt sich dataStruct *p = (dataStruct *)mData interpretieren? ist das (dataStruct *) einfach als Casting zu verstehen?
 
Casting von void Pointer auf dataStruct Pointer.
Wenn du CPP verwendest könntest du das ganze auch so lösen btw:

dataStruct *p = new dataStruct[mWidth*mHeight];
FILE* fp=fopen("data.cis", "rb");
size_t count=fread(p ,sizeof(dataStruct),mWidth*mHeight, fp);
fclose(fp);
......
delete []p;
Ist *etwas* kompakter.
 
Zuletzt bearbeitet:
Mal abgesehen von den fehlenden NULL-Pointer-Prüfungen ist der Quellcode alles andere als Speicher- und Performanceschonend...


Wenn deine width und height Angaben im Quellcode stimmen, dann verbraucht dein new (oder malloc) mal eben knapp 345 MB.


Verarbeite die Datei lieber sequenziell, beispielsweise in 16 kB-Blöcken.
 
Nai schrieb:
Casting von void Pointer auf dataStruct Pointer.
Wenn du CPP verwendest könntest du das ganze auch so lösen btw:

dataStruct *p = new dataStruct[mWidth*mHeight];
FILE* fp=fopen("data.cis", "rb");
size_t count=fread(p ,sizeof(dataStruct),mWidth*mHeight, fp);
fclose(fp);
......
delete []p;
Ist *etwas* kompakter.

Das, was du vorschlägst, wird allerdings nur funktionieren, wenn der Compiler in dataStruct nicht noch irgend welche Paddingbytes einfügt - was er jederzeit darf, es sei denn, du verbietest es ihm irgend wie. Die gängigen Compiler bieten dazu #pragma pack Präprozessordirektiven. Obendrein gibt es dann noch das Problem der Endianness. Arbeitet der Rechner, der deinen Code ausführt, nicht mit dem selben Endiannessformat, das für die Binärdatei festgelegt wurde, kommt da nur Murx raus. Deshalb ist dieses Ich-lese-mal-eben-einen-Binärbatzen-ein-und-caste-dann-einfach-auf-irgeneine-Struktur Geeiere immer mit Vorsicht zu genießen.
 
Zurück
Oben