Bitmap einlesen und Pixmap_Portable ausgeben erfolgt Ausgabe gespiegelt an der y-Achse
-
Hallo Leute,
ich habe hier ein C++ - Programm geschrieben, das eine Bitmap-Datei ausliest, auf Fehler überprüft und zu Testzwecken als Portable_Pixmap-Datei ausgibt. Die Padding Probleme habe ich schon gelöst, jedoch gibt das Programm das erzeugte Bild an der y-Achse gespiegelt wieder aus. Leider habe ich keine Ahnung warum das so ist, kann mir auch nicht vorstellen, woran das liegt.Hier mal das Programm
Header:/* * Bitmap.h * * Created on: 18.11.2011 * Author: heiko */ typedef struct{ unsigned short fileType; unsigned int fileSize; unsigned short reserved1,reserved2; unsigned int offset; } Header; typedef struct{ unsigned int infoheaderSize; int width, height; unsigned short numberOfPlanes; unsigned short bitsPerPixel; unsigned int compression; unsigned int imageSize; int xresolutionPerMeter, yresolutionPerMeter; unsigned int numberOfColours; unsigned int importantColours; }Infoheader; typedef struct{ unsigned char blueValue; unsigned char greenValue; unsigned char redValue; unsigned char rgbReserved; }RgbQuad;
Source-Datei:
/* * Bitmap.cpp * * Created on: 18.11.2011 * Author: heiko */ // Probleme beim Übersetzen über die Shell -> Seitenlange Fehlermeldung // Die Ausgabe der Bilder erfolgt korrekt, jedoch gespiegelt an der y-Achse #include "Bitmap.h" #include <fstream> #include <iostream> #include <ostream> //#include <stdio.h> //#include <stdlib.h> #include <vector> #include <string> using namespace std; int main(int argc, char * argv[]){ ifstream bmpInput; bmpInput.open(argv[1], ifstream::in); if(!bmpInput){ cerr << "could not open file" << endl; bmpInput.close(); } bool padding = false; unsigned int posGetPointer = 0; //Header einlesen Header header; bmpInput.read((char*)(&header.fileType), sizeof(header.fileType)); if(bmpInput.eof()) return 0; posGetPointer += sizeof(header.fileType); bmpInput.seekg(posGetPointer); //testen ob richtiges Format unsigned short M = 'M'; unsigned short B = 'B'; unsigned short MB = (M<<8) + B; if(header.fileType != MB){ cerr << "Falsches Format von FileType" << endl; bmpInput.close(); return 0; } if(bmpInput.eof()) return 0; bmpInput.read((char*)(&header.fileSize), sizeof(header.fileSize)); posGetPointer += sizeof(header.fileSize); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&header.reserved1), sizeof(header.reserved1)); posGetPointer += sizeof(header.reserved1); bmpInput.seekg(posGetPointer); //testen ob reserved1 != 0 if(header.reserved1 != 0){ cerr << "reserved1 != 0" << endl; bmpInput.close(); return 0; } if(bmpInput.eof()) return 0; bmpInput.read((char*)(&header.reserved2), sizeof(header.reserved2)); posGetPointer += sizeof(header.reserved2); bmpInput.seekg(posGetPointer); //testen ob reserved2 != 0 if(header.reserved2 != 0){ cerr << "reserved2 != 0" << endl; bmpInput.close(); return 0; } if(bmpInput.eof()) return 0; bmpInput.read((char*)(&header.offset), sizeof(header.offset)); posGetPointer += sizeof(header.offset); bmpInput.seekg(posGetPointer); //Infoheader einlesen Infoheader infheader; if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.infoheaderSize), sizeof(infheader.infoheaderSize)); posGetPointer += sizeof(infheader.infoheaderSize); bmpInput.seekg(posGetPointer); //testen ob infoheaderSize != 40 if(infheader.infoheaderSize != 40){ cerr << "InfoheaderSize != 40" << endl; bmpInput.close(); return 0; } if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.width), sizeof(infheader.width)); posGetPointer += sizeof(infheader.width); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.height), sizeof(infheader.height)); posGetPointer += sizeof(infheader.height); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.numberOfPlanes), sizeof(infheader.numberOfPlanes)); posGetPointer += sizeof(infheader.numberOfPlanes); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.bitsPerPixel), sizeof(infheader.bitsPerPixel)); posGetPointer += sizeof(infheader.bitsPerPixel); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.compression), sizeof(infheader.compression)); posGetPointer += sizeof(infheader.compression); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.imageSize), sizeof(infheader.imageSize)); posGetPointer += sizeof(infheader.imageSize); bmpInput.seekg(posGetPointer); //testen ob filesize = imageSize + offset if(header.fileSize > header.offset + infheader.imageSize){ cerr << "fileSize zu groß. Erwartet: " << header.offset + infheader.imageSize << ", tatsächlich: " << header.fileSize << endl; bmpInput.close(); return 0; } else if(header.fileSize < header.offset + infheader.imageSize){ cerr << "fileSize zu klein. Erwartet: " << header.offset + infheader.imageSize << ", tatsächlich: " << header.fileSize << endl; bmpInput.close(); return 0; } if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.xresolutionPerMeter), sizeof(infheader.xresolutionPerMeter)); posGetPointer += sizeof(infheader.xresolutionPerMeter); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.yresolutionPerMeter), sizeof(infheader.yresolutionPerMeter)); posGetPointer += sizeof(infheader.yresolutionPerMeter); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.numberOfColours), sizeof(infheader.numberOfColours)); posGetPointer += sizeof(infheader.numberOfColours); bmpInput.seekg(posGetPointer); //offset-Größe testen if(header.offset > 54 + infheader.numberOfColours*4){ cerr << "Offset zu groß. Erwartet:" << 54 + infheader.numberOfColours*4 << ", tatsächlich: " << header.offset << endl; bmpInput.close(); return 0; } else if(header.offset < 54 + infheader.numberOfColours*4){ cerr << "Offset zu klein. Erwartet:" << 54 + infheader.numberOfColours*4 << ", tatsächlich: " << header.offset << endl; bmpInput.close(); return 0; } if(bmpInput.eof()) return 0; bmpInput.read((char*)(&infheader.importantColours), sizeof(infheader.importantColours)); posGetPointer += sizeof(infheader.importantColours); bmpInput.seekg(posGetPointer); RgbQuad colours[16]; for(int i = 0; i < 16; ++i){ if(bmpInput.eof()) return 0; bmpInput.read((char*)(&colours[i].blueValue), sizeof(char)); posGetPointer += sizeof(char); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&colours[i].greenValue), sizeof(char)); posGetPointer += sizeof(char); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&colours[i].redValue), sizeof(char)); posGetPointer += sizeof(char); bmpInput.seekg(posGetPointer); if(bmpInput.eof()) return 0; bmpInput.read((char*)(&colours[i].rgbReserved), sizeof(char)); posGetPointer += sizeof(char); bmpInput.seekg(posGetPointer); } //festellen ob padding notwendig ist if((infheader.width/2 + infheader.width%2)%4 != 0) padding = true; //Pixel-Daten werden im Vektor imageData gespeichert std::vector<unsigned char> imageData; unsigned char imgDat; //Anzahl der zu entfernenden Leerbytes festlegen int toRemove = 0; if(padding){ toRemove = 4 - (infheader.width/2 + infheader.width%2)%4; } for(int height = 0; height < infheader.height; ++height){ for(int width = 0; width < (infheader.width/2 + infheader.width%2 + toRemove); ++width){ if(bmpInput.eof()){ cerr << "es konnten nicht alle images gelesen werden" << endl; return 0; } bmpInput.read((char*)(&imgDat), sizeof(char)); imageData.push_back(imgDat); posGetPointer += sizeof(char); bmpInput.seekg(posGetPointer); } if(padding){ for(int i = 0; i < toRemove; ++i){ imageData.pop_back(); } } } cout << "statistische Daten: " << endl << "Dateigröße: " << header.fileSize << " Byte" << endl << "Auflösung: " << infheader.width << "x" << infheader.height << " in Megapixel: " << (double)(infheader.width*infheader.height)/1000000 << endl << "Padding benötigt: "; if(padding) cout << "ja" << endl; else cout << "nein" << endl; bmpInput.close(); //Ausgaben in Portable_Pixmap-Datei (.ppm) fstream bmpOutput("./smiley.ppm", fstream::in|fstream::out|fstream::trunc); if(!bmpOutput){ cerr << "could not open file" << endl; bmpOutput.close(); } bool oddWidth; if(infheader.width%2 != 0) oddWidth = true; bmpOutput << "P6"<< " " << infheader.width << " "<< infheader.height<< " " << 255; for(unsigned int i = imageData.size() - 1; i >= 0; --i){ unsigned char upper, lower; upper = ((imageData[i])& 0xf0)>>4; lower = (imageData[i])& 0x0f; if(oddWidth && (i % (infheader.width/2 + 1) == 0)){ bmpOutput << (unsigned char) colours[upper].blueValue << (unsigned char)colours[upper].redValue << (unsigned char)colours[upper].greenValue; } else{ bmpOutput << (unsigned char) colours[lower].blueValue << (unsigned char)colours[lower].redValue << (unsigned char)colours[lower].greenValue << (unsigned char)colours[upper].blueValue << (unsigned char)colours[upper].redValue << (unsigned char)colours[upper].greenValue; } } bmpOutput.close(); }
Weiteres Problem:
das Programm lässt sich nur in Eclipse kompilieren und ausführen. Wenn ich versuche das Programm auf der Shell mit gcc zu übersetzen, gibt der Compiler eine Seitenlange Fehlermeldung ausDanke schon mal für eure Hilfe