Bitmap Loader problem

Started by
2 comments, last by Etherstar 20 years, 10 months ago
Im getting some weird runtime error with my bitmap loader. Debugger is teeling me im not allocating memory right somehow. Any help would be greatly appreciated.

// 16 bit Bitmap Loader // CBMPLoader.h


#include <fstream>
#include <string>
using namespace std;
#include <windows.h>
#include <windowsx.h>
#include "DDraw.h"

#define DDRAW_INIT_STRUCT(ddstruct)

class CBMPLoader
{
public:
	CBMPLoader(const char * szFileName);
	~CBMPLoader();
	void CopyToSurface(LPDIRECTDRAW7 lpDD, LPDIRECTDRAWSURFACE7 lpDDS);
	
private:	
	BITMAPFILEHEADER FileHeader;
	BITMAPINFOHEADER InfoHeader;
	unsigned short * pBuffer; 
};

// CBMPLoader.cpp


#include "CBMPLoader.h"
#include "CErrorReporter.h"

CBMPLoader::CBMPLoader(const char * szFileName)
{
	ifstream fin(szFileName, ios::binary);
	if (!fin)
	{
		CErrorReporter oReporter;
		oReporter.ReportGenError(ET_GENERAL,
			"Unable to open bitmap file.",
			"Unspecified Location.", ER_NONFATAL);
	}
	//	read in bmp file header

	fin.read( (char *) &this->FileHeader, sizeof(BITMAPFILEHEADER));

	//double check that it is a bitmap

	if (this->FileHeader.bfType != 0x4D42) // standard bitmap type...I hope

	{
		CErrorReporter oReporter;
		oReporter.ReportGenError(ET_GENERAL,
			"File Loaded was not a Bitmap!",
			"Unspecified Location", ER_NONFATAL);
	}

	// now load the info header

	fin.read( (char *) &this->InfoHeader, sizeof(BITMAPINFOHEADER));


	// Now we know how much memory we need for the bitmap so we decalre an array

	// on the free store to have an equal size of the Image''s bit size.


	this->pBuffer = new unsigned short[(this->InfoHeader.biHeight)*(this->InfoHeader.biWidth)]; 
	// now copy the image data to our array

	fin.read( (char *) this->pBuffer[0], this->InfoHeader.biSizeImage);

	// everything is stored, lets clean up.


	fin.close();
	
}

CBMPLoader::~CBMPLoader()
{
	delete [] pBuffer; // clean up our video memory

}

void CBMPLoader::CopyToSurface(LPDIRECTDRAW7 lpDD, LPDIRECTDRAWSURFACE7 lpDDS)
{
	// function copies our bitmap to an offscreen surface the same size as the bitmap

	// at a specified at x,y


	DDSURFACEDESC2 DDSD1;

	DDRAW_INIT_STRUCT(DDSD1);

	DDSD1.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

	DDSD1.dwWidth = this->InfoHeader.biWidth;
	DDSD1.dwHeight = this->InfoHeader.biHeight;

	DDSD1.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;

	if (FAILED(lpDD->CreateSurface(&DDSD1, &lpDDS, NULL)))
	{
		CErrorReporter oReporter;
		oReporter.ReportGenError(ET_INIT, "Unable to create offscreen surface",
			"Unspecified Location", ER_FATAL);
	}

	DDRAW_INIT_STRUCT(DDSD1);
	// lets lock it up and copy the color data


	if (FAILED(lpDDS->Lock(NULL, &DDSD1, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
	{
		CErrorReporter oReporter;
			oReporter.ReportGenError(ET_LOCK, "Unable to lock offscreen surface",
				"Unspecified locatation.", ER_NONFATAL);
	}

	unsigned short * pVideo_Buffer = (unsigned short *)DDSD1.lpSurface;
	// now each short will hold one byte of our surfaces memory

 
	// lets copy the memory

	memcpy((void *) pVideo_Buffer, (void *) this->pBuffer[0], this->InfoHeader.biSizeImage);

	// we should be good to go, all the memory is now stored in the surface pointer

	// we passed in, which has been initialized and memory copied. lets unlock and bail


	if (FAILED(lpDDS->Unlock(NULL)))
	{
		CErrorReporter oReporter;
		oReporter.ReportGenError(ET_LOCK, "Unable to unlock surface", 
			"Unspecified location.", ER_NONFATAL);
	}
}

The Error occurse when I try to run CBMPLoader::CopyToSurface. The error I get is: First-chance exception at 0x77e73887 in BitMapping.exe: Microsoft C++ exception: std::bad_alloc @ 0x0012f978. Unhandled exception at 0x77e73887 in BitMapping.exe: Microsoft C++ exception: std::bad_alloc @ 0x0012f978. Etherstar My Site
Advertisement
Try to pass the SURFACE7s as references.
GraphicsWare|RenderTechhttp://www.graphicsware.com3D Graphics & Solutions
Thanks for the help, but passing by reference gave me the same error

Etherstar
My Site
new unsigned short[(this->InfoHeader.biHeight)*(this->InfoHeader.biWidth)];

Are u sure u r loading a 16-bit image? and not 24 bit
Else u should make a conversion routine like this for a r5g6b5 format

int i = 0;
while (i {
char r,g,b;
r = bitmap->buffer[i+2];
g = bitmap->buffer[i+1];
b = bitmap->buffer;
WORD rr,rg,rb;
rr = ((r>>3)<<11);
rg = ((g>>2)<<5);
rb = (b>>3);
WORD temp = rr+rg+rb;
*imagedata = temp;
imagedata++;
i+=3;
}

This topic is closed to new replies.

Advertisement