binär byteweise lesen - Bestimmung des Dateityps einer Bilddatei
-
Ich bekomm das hier einfach nicht zum Laufen. Der gelesene String hat immer zusätzliche Sonderzeichen, egal wieviel ich einlese.
Erkennt irgendwer offensichtliche Fehler? Vorschläge, wie ich das einfacher lösen könnte würden mich genauso freuen.
bool Gif::isPNG(string filename) { string vgl("PNG"); ifstream inf; char buffer[3]; inf.open(filename.c_str(), ios::binary); inf.seekg(1); inf.read(buffer, 3); inf.close(); if (string(buffer) == vgl) return 1; else return 0; }Das funktioniert komischerweise, auch wenn der string eigentlich nur 4 bytes anstatt 8 lang sein sollte:
bool Gif::isJPG(string filename) { string vgl("JFIF"); ifstream inf; char buffer[8]; inf.open(filename.c_str(), ios::binary); inf.seekg(6); inf.read(buffer, 8); inf.close(); if (string(buffer) == vgl) return 1; else return 0; }
-
Du musst die Nullterminierung der char-Arrays beachten, oder du sagst dem Konstruktor von std::string, wie weit er den char* kopieren soll.
-
Maxi schrieb:
Du musst die Nullterminierung der char-Arrays beachten, oder du sagst dem Konstruktor von std::string, wie weit er den char* kopieren soll.
Ja danke, genau das wars.
-
ichbinsisyphos schrieb:
Vorschläge, wie ich das einfacher lösen könnte würden mich genauso freuen.
Da die ersten 8 Bytes eines PNG-Files quasi Text-Kompatibel sind, kannst Du sie auch wie ein Text-File behandeln. Das vereinfacht Dein Problem zu:
bool Gif::isPNG( const std::string& filename ) { using namespace std; ifstream inf( filename.c_str(), ios::binary ); string magic; return inf.ignore(1) >> setw(3) >> magic && magic == "PNG"; }Der Zusatz setw(3) (erfordert #include <iomanip>) ist für die Funktion nicht erforderlich, er schützt aber davor, Unmengen von Daten in den Speicher zu lesen, wenn es kein PNG-File ist.
Gruß
Werner
-
Ja, ist besser. Ich frag mich aber grad ... mit setw(3) wird nur in Blöcken von 3 Zeichen übergeben? Also liefert die Abfrage gleich beim ersten Mal true/false.
Und wenn das fehlt? Müsste er nicht schon beim ersten Zeichen die Strings vergleichen und false liefern oder übergibt er den gesamten Inhalt der Datei? Und werden nur String gleicher Länge verglichen, also zählen dann auch nur die ersten 3 Zeichen? Oder alles, was wieder false liefert?
-
ichbinsisyphos schrieb:
Ich frag mich aber grad ... mit setw(3) wird nur in Blöcken von 3 Zeichen übergeben? Also liefert die Abfrage gleich beim ersten Mal true/false.
Und wenn das fehlt? Müsste er nicht schon beim ersten Zeichen die Strings vergleichen und false liefern oder übergibt er den gesamten Inhalt der Datei? Und werden nur String gleicher Länge verglichen, also zählen dann auch nur die ersten 3 Zeichen? Oder alles, was wieder false liefert?
Ich verstehe Deine Frage nicht so ganz.
setw(3) heißt nur, das maximal 3 Zeichen in die Stringvariable 'magic' gelesen werden. Lässt man das setw(3) weg, so werden so viele Zeichen gelesen bis ein sogenannter White Space Character folgt. Mit andereren Worten: Der Ausdruck istream >> string liest immer ein Wort, wie auch ein Mensch ein Wort lesen würde. Bei einer PNG-Datei ist das 5.Zeichen per Format-Definition ein CR (Code 13 bzw. 0x0D) und das ist ein White Space und damit stoppt das Einlesen an dieser Stelle auch ohne ein setw(..).Gruß
Werner
-
Aso, sowieso nur bis zum ersten whitespace, ok verstehe.