All pastes #897892 Raw Edit

Unnamed

public text v1 · immutable
·published 2008-02-09 22:26 UTC
rendered paste body
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 <cstdlib>
+#include <cstdio>
+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 <cstdio>
+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<unsigned char *>(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;
+}