• 14
• 12
• 9
• 10
• 13

# Terrain from 8-bit bitmap

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

## 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:

THOSE SPIKES AT THE END OF THE TERRAIN!

 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 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..)

##### 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..)

I'm confused, because I don't know how many more bits to read and to what structure.

##### 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 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);