commit d178d71675f3edeadc9f369535bb267d2b45df2c Date: Sat Feb 9 23:23:45 2008 +0100 Make BMP loading work correctly. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5d7852a --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +bmploader: main.cpp bmploader.h fileio.h + g++ `sdl-config --cflags` `sdl-config --libs` -o bmploader main.cpp diff --git a/bmploader.h b/bmploader.h index 6214a2b..9fa152b 100644 --- a/bmploader.h +++ b/bmploader.h @@ -1,7 +1,11 @@ #ifndef bmploader_hpp__ #define bmploader_hpp__ -#include "FileIO.hpp" +#include +#include +using namespace std; + +#include "fileio.h" class BMPClass { @@ -17,26 +21,56 @@ private: int iSize; FileIO BMPFile; public: + class BMPLoadException { + public: + BMPLoadException(const char *reason) : m_reason(reason) {} + + const char *reason() const { return m_reason; } + + private: + const char *m_reason; + }; + char *cpData; - bool LoadBMP(char *cpAddress); + void LoadBMP(char *cpAddress); + int width() const { return iWidth; } + int height() const { return iHeight; } }; -bool BMPClass::LoadBMP(char *cpAddress) +void BMPClass::LoadBMP(char *cpAddress) { int iReadLoc; int iI; - BMPFile.Open(cpAddress); + if (!BMPFile.Open(cpAddress)) + throw BMPLoadException("No such file"); + BMPFile.Read(2,c,0); //Checks If file is BM if(si[0] != 19778) - return false; + throw BMPLoadException("File doesn't have BMP header"); + +#if 0 BMPFile.Read(2,c,6); if(!si[0]) return false; BMPFile.Read(2,c,8); if(!si[0]) return false; +#endif + + BMPFile.Read(4,c,30); + if (i) + throw BMPLoadException("File is compressed"); + + int bpp; + BMPFile.Read(2,c,28); + bpp = si[0]; + printf("bpp: %d\n", bpp); + + if (bpp != 24 && bpp != 32) + throw BMPLoadException("Unsupported bit depth"); + //Gets Width + Height BMPFile.Read(4,c,18); iWidth = i; @@ -46,16 +80,26 @@ bool BMPClass::LoadBMP(char *cpAddress) BMPFile.Read(4,c,10); iReadLoc = i; cpData = new char[iWidth*iHeight*3]; - iI = 0; - while(iI < iWidth*iHeight) - { - BMPFile.Read(3,c,iReadLoc); - cpData[iI*3] = c[0]; - cpData[iI*3+1] = c[1]; - cpData[iI*3+2] = c[2]; - iI++; - iReadLoc += 4; + + printf("image size: %d %d\n", iWidth, iHeight); + + for (int y = 0; y < iHeight; ++y) { + for (int x = 0; x < iWidth; ++x) { + BMPFile.Read(3,c,iReadLoc); + + // BMP's are stored bottom-up so invert y-coordinate + int index = 3 * ((iHeight - y - 1) * iWidth + x); + cpData[index] = c[0]; + cpData[index+1] = c[1]; + cpData[index+2] = c[2]; + + if (bpp == 24) + iReadLoc += 3; + else + iReadLoc += 4; + } } - return true; + + BMPFile.Close(); } #endif diff --git a/fileio.h b/fileio.h index 8f1626f..70b74f2 100644 --- a/fileio.h +++ b/fileio.h @@ -2,12 +2,16 @@ #define fileio_hpp_ #include +using namespace std; class FileIO { private: FILE *pFile; public: + FileIO() : pFile(0) {} + ~FileIO() { Close(); } + bool Open(char *cpFileName); void Close(); bool Read(int iAmount,char *cpDataBuffer,int iStartPoint); @@ -19,15 +23,23 @@ public: bool FileIO::Open(char *cpFileName) { - if(!cpFileName) + if (!cpFileName) return false; - fopen_s(&pFile,cpFileName,"a+"); + + pFile = fopen(cpFileName, "r"); + + if (!pFile) + return false; + return true; } void FileIO::Close() { - fclose(pFile); + if (pFile) { + fclose(pFile); + pFile = 0; + } } bool FileIO::Read(int iAmount,char *cpDataBuffer,int iStartPoint) @@ -37,7 +49,7 @@ bool FileIO::Read(int iAmount,char *cpDataBuffer,int iStartPoint) if(fseek(pFile,iStartPoint,SEEK_SET)) return false; else - fgets(cpDataBuffer,iAmount,pFile); + fread(cpDataBuffer,1,iAmount,pFile); return true; } diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..86e7e2c --- /dev/null +++ b/main.cpp @@ -0,0 +1,52 @@ +#include "bmploader.h" +#include "SDL.h" + +int main(int argc, char **argv) +{ + if (argc < 2) { + printf("Usage: %s filename\n", argv[0]); + return 1; + } + + SDL_Surface *window; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("Failed to initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + atexit(SDL_Quit); + + BMPClass bmp; + try { + bmp.LoadBMP(argv[1]); + } catch (const BMPClass::BMPLoadException &exception) { + printf("BMP loading failed: %s\n", exception.reason()); + return 1; + } + + window = SDL_SetVideoMode(bmp.width(), bmp.height(), 32, SDL_SWSURFACE); + + if (!window) { + printf("Failed to create SDL window: %s\n", SDL_GetError()); + return 1; + } + + unsigned char *dst = reinterpret_cast(window->pixels); + + SDL_Event event; + while (!SDL_PollEvent(&event) || event.type != SDL_QUIT) { + for (int y = 0; y < bmp.height(); ++y) { + for (int x = 0; x < bmp.width(); ++x) { + int srcIndex = 3 * (y * bmp.width() + x); + int dstIndex = 4 * (y * bmp.width() + x); + + for (int i = 0; i < 3; ++i) + dst[dstIndex + i] = bmp.cpData[srcIndex + i]; + } + } + SDL_Flip(window); + } + + return 0; +}