Jump to content
  • Advertisement
Sign in to follow this  
Drakkcon

Can someone help me fix my bitmap loader?

This topic is 4768 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

#include "SDL.h"

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

void SetPixel8Bit(SDL_Surface *surface, int x, int y, Uint8 Color);
void SetPixel32Bit(SDL_Surface *surface, int x, int y, Uint32 Color);
SDL_Surface * Load24BitBitmap(char *FileName);

struct BitmapFileHeader
{
    unsigned short bfType; //must be 19778
    unsigned int bfSize;
    unsigned short bfReserved1, bfReserved2;
    unsigned int bfOffBits;
};

struct BitmapInfoHeader
{
    unsigned int biSize;
    unsigned int biWidth;
    unsigned int biHeight;
    unsigned short biPlanes;
    unsigned short biBitCount;
    unsigned int biCompression;
    unsigned int biSizeImage;
    unsigned int biXPelsPerMeter;
    unsigned int biYPelsPerMeter;
    unsigned int biClrUsed;
    unsigned int biClrImportant;
};

struct RgbQuadLilEndian
{
    char rgbBlue;
    char rgbGreen;
    char rgbRed;
    char rgbReserved;
};

struct Bitmap
{
    BitmapFileHeader BitmapFile;
    BitmapInfoHeader BitmapInfo;
    RgbQuadLilEndian* BitmapData;
};

int main(int argc, char **argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    
    SDL_Surface *screen = SDL_SetVideoMode
        (640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    
    srand(time(NULL));
    
    SDL_Surface *image = Load24BitBitmap("test2.bmp");
    
    SDL_BlitSurface(image, NULL, screen, NULL);
    
    SDL_Flip(screen);
    
    SDL_Delay(2000);
    
    SDL_Quit();
    
    
    return 0;
}

void SetPixel8Bit(SDL_Surface *surface, int x, int y, Uint8 Color)
{
    Uint8 *bufp;
    bufp = (Uint8 *)surface->pixels + y*surface->pitch + x;
    *bufp = Color;
}

void SetPixel32Bit(SDL_Surface *surface, int x, int y, Uint32 Color)
{
     Uint32 *pBuf = (Uint32*)surface->pixels + y * surface->pitch/4 + x;
    *(Uint32*)pBuf = Color;
}

SDL_Surface* Load24BitBitmap(char *FileName)
{
    Bitmap BitmapToLoad;  //bitmap structure
    SDL_Surface *surface; //surface to load the bitmap to
    
    fstream File(FileName, ios::in | ios::binary); //open bitmap file
    //load the bitmap File Header
    File.read((char*)&BitmapToLoad.BitmapFile.bfType, sizeof(unsigned short));
    File.read((char*)&BitmapToLoad.BitmapFile.bfSize, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapFile.bfReserved1, sizeof(unsigned short));
    File.read((char*)&BitmapToLoad.BitmapFile.bfReserved2, sizeof(unsigned short));
    File.read((char*)&BitmapToLoad.BitmapFile.bfOffBits, sizeof(unsigned int));
    //load the bitmap data header
    File.read((char*)&BitmapToLoad.BitmapInfo.biSize, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biWidth, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biHeight, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biPlanes, sizeof(unsigned short));
    File.read((char*)&BitmapToLoad.BitmapInfo.biBitCount, sizeof(unsigned short));
    File.read((char*)&BitmapToLoad.BitmapInfo.biCompression, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biSizeImage, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biXPelsPerMeter, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biYPelsPerMeter, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biClrUsed, sizeof(unsigned int));
    File.read((char*)&BitmapToLoad.BitmapInfo.biClrImportant, sizeof(unsigned int));
    
    int TotalPixels = BitmapToLoad.BitmapInfo.biWidth * BitmapToLoad.BitmapInfo.biHeight;
    
    BitmapToLoad.BitmapData = new RgbQuadLilEndian[TotalPixels];
    
    int Width = BitmapToLoad.BitmapInfo.biWidth;
    int Height = BitmapToLoad.BitmapInfo.biHeight;
    
    //Load the rest of the file, minus the BitmapFile & BitmapInfo (which are 54 bytes total)
    File.read((char*)&BitmapToLoad.BitmapData, BitmapToLoad.BitmapFile.bfSize - 
                        (sizeof(BitmapToLoad.BitmapFile) - sizeof(BitmapToLoad.BitmapInfo)));

    File.close();
    
    //draw the pixel data bottom to top because that's how a BMP is stored  
    for(int i = 0; i == Width; ++i)
        for(int j = Height; j == 0; --j)
        {
            char r = BitmapToLoad.BitmapData[i*j].rgbRed;
            char b = BitmapToLoad.BitmapData[i*j].rgbBlue;
            char g = BitmapToLoad.BitmapData[i*j].rgbGreen;
            SetPixel32Bit(surface, i, j, SDL_MapRGB(surface->format, r, g, b));
        }
        
    delete BitmapToLoad.BitmapData;
    
    return surface;
}


Whenever I run my program it exits immediately. On debug I get a segmentation fault, but that's all the debugger tells me (it won't tell me where). I'm using MinGW. Can someone help? PS: Don't tell me to use SDL_Image. I'm doing this for the sake of knowledge, not a professional project.

Share this post


Link to post
Share on other sites
Advertisement
Well, first off, do any of those read() calls fail?
Does surface need allocated/initialized?
Does SetPixel... fail?

And I've never encountered a debugger that doesn't say where access violations occur. Even if it doesn't, set a breakpoint at the beginning of the function and step through until it dies. That'll give you a great indication of where it dies, which should narrow down the possible reasons why it dies.

Share this post


Link to post
Share on other sites
Quote:
Original post by Telastyn
Well, first off, do any of those read() calls fail?
Does surface need allocated/initialized?
Does SetPixel... fail?

And I've never encountered a debugger that doesn't say where access violations occur. Even if it doesn't, set a breakpoint at the beginning of the function and step through until it dies. That'll give you a great indication of where it dies, which should narrow down the possible reasons why it dies.


Thanks I'll try that.

Quote:

use SDL_LoadBMP, it is built in to SDL. Might as well use it.


for the sake of knowledge.

Share this post


Link to post
Share on other sites
No that didn't fix it.
I have already tested that exact set pixel function. It works perfectly.
Oh. And the debugger that comes with Dev-C++ is extremly glitchy and poor. It only gives me the information about half of the time.

Share this post


Link to post
Share on other sites

#include "SDL.h"

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define RMASK 0xFF000000
#define BMASK 0x00FF0000
#define GMASK 0x0000FF00
#define AMASK 0x000000FF
#else
#define AMASK 0xFF000000
#define BMASK 0x00FF0000
#define GMASK 0x0000FF00
#define RMASK 0x000000FF
#endif

using namespace std;

void SetPixel8Bit(SDL_Surface *surface, int x, int y, Uint8 Color);
void SetPixel32Bit(SDL_Surface *surface, int x, int y, Uint32 Color);
SDL_Surface * Load24BitBitmap(char *FileName);

struct BitmapFileHeader
{
unsigned short bfType; //must be 19778
unsigned int bfSize;
unsigned short bfReserved1, bfReserved2;
unsigned int bfOffBits;
};

struct BitmapInfoHeader
{
unsigned int biSize;
unsigned int biWidth;
unsigned int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
unsigned int biXPelsPerMeter;
unsigned int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
};

struct RgbQuadLilEndian
{
char rgbReserved;
char rgbBlue;
char rgbGreen;
char rgbRed;
};

struct Bitmap
{
BitmapFileHeader BitmapFile;
BitmapInfoHeader BitmapInfo;
RgbQuadLilEndian* BitmapData;
};

int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_VIDEO);

SDL_Surface *screen = SDL_SetVideoMode
(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

srand(time(NULL));

SDL_Surface *image = Load24BitBitmap("test2.bmp");

SDL_BlitSurface(image, NULL, screen, NULL);

SDL_Flip(screen);

SDL_Delay(2000);

SDL_Quit();


return 0;
}

void SetPixel8Bit(SDL_Surface *surface, int x, int y, Uint8 Color)
{
Uint8 *bufp;
bufp = (Uint8 *)surface->pixels + y*surface->pitch + x;
*bufp = Color;
}

void SetPixel32Bit(SDL_Surface *surface, int x, int y, Uint32 Color)
{
Uint32 *pBuf = (Uint32*)surface->pixels + y * surface->pitch/4 + x;
*(Uint32*)pBuf = Color;
}

SDL_Surface* Load24BitBitmap(char *FileName)
{
Bitmap BitmapToLoad; //bitmap structure
SDL_Surface *surface; //surface to load the bitmap to

fstream File(FileName, ios::in | ios::binary); //open bitmap file
//load the bitmap File Header
File.read((char*)&BitmapToLoad.BitmapFile.bfType, sizeof(unsigned short));
File.read((char*)&BitmapToLoad.BitmapFile.bfSize, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapFile.bfReserved1, sizeof(unsigned short));
File.read((char*)&BitmapToLoad.BitmapFile.bfReserved2, sizeof(unsigned short));
File.read((char*)&BitmapToLoad.BitmapFile.bfOffBits, sizeof(unsigned int));
//load the bitmap data header
File.read((char*)&BitmapToLoad.BitmapInfo.biSize, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biWidth, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biHeight, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biPlanes, sizeof(unsigned short));
File.read((char*)&BitmapToLoad.BitmapInfo.biBitCount, sizeof(unsigned short));
File.read((char*)&BitmapToLoad.BitmapInfo.biCompression, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biSizeImage, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biXPelsPerMeter, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biYPelsPerMeter, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biClrUsed, sizeof(unsigned int));
File.read((char*)&BitmapToLoad.BitmapInfo.biClrImportant, sizeof(unsigned int));

int TotalPixels = BitmapToLoad.BitmapInfo.biWidth * BitmapToLoad.BitmapInfo.biHeight;

BitmapToLoad.BitmapData = new RgbQuadLilEndian[TotalPixels];

int Width = BitmapToLoad.BitmapInfo.biWidth;
int Height = BitmapToLoad.BitmapInfo.biHeight;

//Load the rest of the file, minus the BitmapFile & BitmapInfo (which are 54 bytes total)
File.read((char*)&BitmapToLoad.BitmapData, BitmapToLoad.BitmapFile.bfSize -
BitmapToLoad.BitmapFile.bfOffBits);

File.close();

surface = SDL_CreateRGBSurface
(SDL_HWSURFACE, Width, Height, 32, RMASK, GMASK, BMASK, AMASK);

//draw the pixel data bottom to top because that's how a BMP is stored
for(int i = 0; i == Width; ++i)
for(int j = Height; j == 0; --j)
{
char r = BitmapToLoad.BitmapData[i*j].rgbRed;
char b = BitmapToLoad.BitmapData[i*j].rgbBlue;
char g = BitmapToLoad.BitmapData[i*j].rgbGreen;
SetPixel32Bit(surface, i, j, SDL_MapRGB(surface->format, r, g, b));
}

delete BitmapToLoad.BitmapData;

return surface;
}



This is the updated source.

Share this post


Link to post
Share on other sites

for(int i = 0; i == Width; ++i)
for(int j = Height; j == 0; --j)


Eh? Aren't those 2nd params supposed to be != or perpaps even < or <=?

Share this post


Link to post
Share on other sites
I feel horrifically stupid right now. You have to understand, it's late right now :) Hold on.
No, it still doesn't work.

Edit:
And now that I've rebuilt my project it's telling me where the seg fault is, so I'm going to try again.

[Edited by - Drakkcon on June 30, 2005 11:09:59 PM]

Share this post


Link to post
Share on other sites
Okay, this makes no sense. It's telling me that there's a segmentation fault on this line:

char r = BitmapToLoad.BitmapData[i*j].rgbRed;
it says that i * j = 0

Um, is that a problem? Don't arrays count from 0?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!