Jump to content
  • Advertisement
Sign in to follow this  
Marusu

Terrain from 8-bit bitmap

This topic is 2711 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

Hi, I have a problem with terrain.
I have witten my own image loader which is supposed to handle 8 and 24 bit BMPs, but for some reasen and ONLY with some 8bit BMPs i get a following bug:
Project%202011-01-16%2013-16-46-54.jpg
THOSE SPIKES AT THE END OF THE TERRAIN!

Here's how I read BMPs:
DWORD nBytes;

HANDLE hFile = CreateFile(wszName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
NULL, NULL);

if (!ReadFile(hFile, (void*)&m_bitmapFH, sizeof(BITMAPFILEHEADER), &nBytes, 0))
{
m_bFailed = true;
return;
}

if (!ReadFile(hFile, (void*)&m_bitmapIH, sizeof(BITMAPINFOHEADER), &nBytes, 0))
{
m_bFailed = true;
return;
}

if (m_bitmapIH.biBitCount == 8)
{
BYTE* pChars = new BYTE[m_bitmapIH.biWidth * m_bitmapIH.biHeight];
if (!ReadFile(hFile, (void*)pChars, m_bitmapIH.biWidth * m_bitmapIH.biHeight * sizeof(BYTE),
&nBytes, 0))
{
m_bFailed = true;
return;
}

m_pRGB = new RGBTRIPLE[m_bitmapIH.biWidth * m_bitmapIH.biHeight];
for (LONG i = 0; i < m_bitmapIH.biWidth * m_bitmapIH.biHeight; i++)
{
m_pRGB.rgbtRed = pChars;
m_pRGB.rgbtGreen = 0;
m_pRGB.rgbtBlue = 0;
}
delete [] pChars;
}
else if (m_bitmapIH.biBitCount == 24)
{
m_pRGB = new RGBTRIPLE[m_bitmapIH.biWidth * m_bitmapIH.biHeight];
if (!ReadFile(hFile, (void*)m_pRGB, m_bitmapIH.biWidth * m_bitmapIH.biHeight * sizeof(RGBTRIPLE),
&nBytes, 0))
{
m_bFailed = true;
return;
}
}
else
{
m_bFailed = true;
return;
}

CloseHandle(hFile);


Any help would be appreciated :)

Have a nice day,
Martin

Share this post


Link to post
Share on other sites
Advertisement
You don't seem to read the color-table in the 8-bit version, are you sure that the color table index exactly corresponds to the color?
Sometimes white and black are always placed first in the color table, so then white would actually have index 0 or 1, instead of 255. Inspect the color table to make sure, either in code or you can probably see it in Photoshop or a similar program.

(There can also padding in BMPs if your width isn't divisible by 4..)

Share this post


Link to post
Share on other sites

You don't seem to read the color-table in the 8-bit version, are you sure that the color table index exactly corresponds to the color?
Sometimes white and black are always placed first in the color table, so then white would actually have index 0 or 1, instead of 255. Inspect the color table to make sure, either in code or you can probably see it in Photoshop or a similar program.

(There can also padding in BMPs if your width isn't divisible by 4..)


Thanks for reply, but how should I read the color table?
I'm confused, because I don't know how many more bits to read and to what structure.

Share this post


Link to post
Share on other sites
If I remember correctly it's right after the BITMAPINFOHEADER. You don't seem to check for the offset to the image data either, so perhaps you interpret the color table as image data, if you have one in your file. If you check the documentation for BITMAPFILEHEADER you see that the bmOffBits contains the distance in bytes from the beginning of the file to the actual bitmap data. So before you ReadFile into pChars, you should probably use SetFilePointer(hFile, header.bmOffBits, NULL, FILE_BEGIN) to move to the correct position in the file before you start reading.

See the BITMAPINFO documentation for details on how to obtain the color table and how many entries there are. However, you might not need the color table for a gray-scale image, so you probably don't have to bother. But still, you need to get the correct offset to the image data if there is a color table.

If you want more detailed information on the file format, try http://en.wikipedia.org/wiki/BMP_file_format

Share this post


Link to post
Share on other sites
Thanks man, you have really helped me! :)
I was also about to ask what method to use for HANDLE to travel that offset and you even have written that.

In case someone else encouters this problem, here's working code:
DWORD nBytes;

HANDLE hFile = CreateFile(wszName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
NULL, NULL);

if (!ReadFile(hFile, (void*)&m_bitmapFH, sizeof(BITMAPFILEHEADER), &nBytes, 0))
{
CloseHandle(hFile);
m_bFailed = true;
return;
}

if (!ReadFile(hFile, (void*)&m_bitmapIH, sizeof(BITMAPINFOHEADER), &nBytes, 0))
{
CloseHandle(hFile);
m_bFailed = true;
return;
}

if (m_bitmapIH.biBitCount == 8)
{
SetFilePointer(hFile, m_bitmapFH.bfOffBits, NULL, FILE_BEGIN);
BYTE* pChars = new BYTE[m_bitmapIH.biWidth * m_bitmapIH.biHeight];
if (!ReadFile(hFile, (void*)pChars, m_bitmapIH.biWidth * m_bitmapIH.biHeight * sizeof(BYTE),
&nBytes, 0))
{
CloseHandle(hFile);
m_bFailed = true;
return;
}

m_pRGB = new RGBTRIPLE[m_bitmapIH.biWidth * m_bitmapIH.biHeight];
for (LONG i = 0; i < m_bitmapIH.biWidth * m_bitmapIH.biHeight; i++)
{
m_pRGB.rgbtRed = pChars;
m_pRGB.rgbtGreen = 0;
m_pRGB.rgbtBlue = 0;
}
delete [] pChars;
}
else if (m_bitmapIH.biBitCount == 24)
{
m_pRGB = new RGBTRIPLE[m_bitmapIH.biWidth * m_bitmapIH.biHeight];
if (!ReadFile(hFile, (void*)m_pRGB, m_bitmapIH.biWidth * m_bitmapIH.biHeight * sizeof(RGBTRIPLE),
&nBytes, 0))
{
CloseHandle(hFile);
m_bFailed = true;
return;
}
}
else
{
CloseHandle(hFile);
m_bFailed = true;
return;
}

CloseHandle(hFile);

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!