Code:
void CheckTerrainHeights()
{
unsigned char TerrainData[131072];
unsigned int ArrayIndex = 0;
int CurrentHeight = 0; // you start here
int MaxHeightPx = 0;
double MaxHeightFt = 0.0;
unsigned int MaxHeightLocation = 0;
int MinHeightPx = 0;
double MinHeightFt = 0.0;
unsigned int MinHeightLocation = 0;
int Errors = 0;
unsigned int ImageArrayIndex = 0;
double ImageTargetHeight = 0.0;
double ImageTerrainHeight = 0.0;
unsigned int BitPos = 0;
unsigned int ByteBlock = 0;
unsigned int ImageBaseArrayIndex = 0;
unsigned char TerrainPreviewData[2097152];
unsigned char Colors[8] = {0, 0, 0, 0, 255, 255, 255, 0};
BITMAPFILEHEADER TempFileHead;
BITMAPINFOHEADER TempInfoHead;
FileHandle = fopen("C:\\My Documents\\My programs\\Terrain height test.bmp", "rb"); // first, read the data
fseek(FileHandle, 1078, SEEK_SET); // skip the header straight to the main data
fread(&TerrainData, 1, 131072, FileHandle);
fclose(FileHandle);
TempFileHead.bfType = 19778; // fills out the structures // 19778 supposedly is "BM"
TempFileHead.bfSize = 2097214; // array length plus off bits (or 62)
TempFileHead.bfReserved1 = 0;
TempFileHead.bfReserved2 = 0;
TempFileHead.bfOffBits = 62;
TempInfoHead.biSize = 40;
TempInfoHead.biWidth = 131072;
TempInfoHead.biHeight = 128;
TempInfoHead.biPlanes = 1;
TempInfoHead.biBitCount = 1; // monochrome bitmap
TempInfoHead.biCompression = BI_RGB; // no compression
TempInfoHead.biSizeImage = 2097152; // the array size
TempInfoHead.biXPelsPerMeter = 2835;
TempInfoHead.biYPelsPerMeter = 2835;
TempInfoHead.biClrUsed = 2; // black and white only
TempInfoHead.biClrImportant = 2; // both possible are important
FileHandle = fopen("C:\\My Documents\\My programs\\Terrain height test heights.bmp", "wb"); // prepare to write a BMP file
fwrite(&TempFileHead.bfType, 2, 1, FileHandle);
fwrite(&TempFileHead.bfSize, 4, 1, FileHandle);
fwrite(&TempFileHead.bfReserved1, 2, 1, FileHandle);
fwrite(&TempFileHead.bfReserved2, 2, 1, FileHandle);
fwrite(&TempFileHead.bfOffBits, 4, 1, FileHandle);
fwrite(&TempInfoHead.biSize, 4, 1, FileHandle);
fwrite(&TempInfoHead.biWidth, 4, 1, FileHandle);
fwrite(&TempInfoHead.biHeight, 4, 1, FileHandle);
fwrite(&TempInfoHead.biPlanes, 2, 1, FileHandle);
fwrite(&TempInfoHead.biBitCount, 2, 1, FileHandle);
fwrite(&TempInfoHead.biCompression, 4, 1, FileHandle);
fwrite(&TempInfoHead.biSizeImage, 4, 1, FileHandle);
fwrite(&TempInfoHead.biXPelsPerMeter, 4, 1, FileHandle);
fwrite(&TempInfoHead.biYPelsPerMeter, 4, 1, FileHandle);
fwrite(&TempInfoHead.biClrUsed, 4, 1, FileHandle);
fwrite(&TempInfoHead.biClrImportant, 4, 1, FileHandle);
fwrite(&Colors, 1, 8, FileHandle); // the colors black then white
while ((ArrayIndex < 131072) && (TerrainData[ArrayIndex] != 4)) // loop until the end or unfinished areas are reached
{
if (TerrainData[ArrayIndex] == 135) { CurrentHeight -= 340; } // steepest downward slope
else if (TerrainData[ArrayIndex] == 151) { CurrentHeight -= 224; }
else if (TerrainData[ArrayIndex] == 167) { CurrentHeight -= 165; }
else if (TerrainData[ArrayIndex] == 183) { CurrentHeight -= 129; }
else if (TerrainData[ArrayIndex] == 199) { CurrentHeight -= 104; }
else if (TerrainData[ArrayIndex] == 215) { CurrentHeight -= 86; }
else if (TerrainData[ArrayIndex] == 231) { CurrentHeight -= 72; }
else if (TerrainData[ArrayIndex] == 247) { CurrentHeight -= 60; }
else if (TerrainData[ArrayIndex] == 0) { CurrentHeight -= 50; }
else if (TerrainData[ArrayIndex] == 16) { CurrentHeight -= 42; }
else if (TerrainData[ArrayIndex] == 32) { CurrentHeight -= 35; }
else if (TerrainData[ArrayIndex] == 48) { CurrentHeight -= 28; }
else if (TerrainData[ArrayIndex] == 64) { CurrentHeight -= 22; }
else if (TerrainData[ArrayIndex] == 80) { CurrentHeight -= 16; }
else if (TerrainData[ArrayIndex] == 96) { CurrentHeight -= 11; }
else if (TerrainData[ArrayIndex] == 112) { CurrentHeight -= 5; }
else if (TerrainData[ArrayIndex] == 128) { CurrentHeight += 0; }
else if (TerrainData[ArrayIndex] == 143) { CurrentHeight += 5; }
else if (TerrainData[ArrayIndex] == 159) { CurrentHeight += 11; }
else if (TerrainData[ArrayIndex] == 175) { CurrentHeight += 16; }
else if (TerrainData[ArrayIndex] == 191) { CurrentHeight += 22; }
else if (TerrainData[ArrayIndex] == 207) { CurrentHeight += 28; }
else if (TerrainData[ArrayIndex] == 223) { CurrentHeight += 35; }
else if (TerrainData[ArrayIndex] == 239) { CurrentHeight += 42; }
else if (TerrainData[ArrayIndex] == 255) { CurrentHeight += 50; }
else if (TerrainData[ArrayIndex] == 8) { CurrentHeight += 60; }
else if (TerrainData[ArrayIndex] == 24) { CurrentHeight += 72; }
else if (TerrainData[ArrayIndex] == 40) { CurrentHeight += 86; }
else if (TerrainData[ArrayIndex] == 56) { CurrentHeight += 104; }
else if (TerrainData[ArrayIndex] == 72) { CurrentHeight += 129; }
else if (TerrainData[ArrayIndex] == 88) { CurrentHeight += 165; }
else if (TerrainData[ArrayIndex] == 104) { CurrentHeight += 224; }
else if (TerrainData[ArrayIndex] == 120) { CurrentHeight += 340; } // steepest upward slope
else { Errors++; printf("Invalid color at location %d\n", ArrayIndex); } // error occurred!
if (CurrentHeight > MaxHeightPx) { MaxHeightPx = CurrentHeight; MaxHeightLocation = ArrayIndex;} // logs minimums and maximums
if (CurrentHeight < MinHeightPx) { MinHeightPx = CurrentHeight; MinHeightLocation = ArrayIndex;}
ImageTerrainHeight = CurrentHeight/60.0+0.5;
BitPos = (unsigned int)(ImageTerrainHeight+16.0) % 8; // find bit position to write to - order is 128, 64, 32, 16, 8, 4, 2, then 1
ByteBlock = 0;
ImageArrayIndex = 0;
while (ByteBlock < 16) // 16 bytes, 128 pixels // each byte block is 26.4 feet // this loop causes stack overflow
{
ImageTargetHeight = ((double)ByteBlock-1.0)*26.4;
ImageBaseArrayIndex = ArrayIndex*16+ByteBlock;
if (ImageTerrainHeight < ImageTargetHeight) // if below, it should be all black // causes stack overflow
{
TerrainPreviewData[ImageBaseArrayIndex] = 0; // all 8 pixels are black
}
else if (ImageTerrainHeight > ImageTargetHeight+26.4) // if above the next step, it should be all white // causes stack overflow
{
TerrainPreviewData[ImageBaseArrayIndex] = 255; // all 8 pixels are white
}
else
{
if (BitPos == 0) { TerrainPreviewData[ImageBaseArrayIndex] = 0; } // more white added for higher BitPos values
else if (BitPos == 1) { TerrainPreviewData[ImageBaseArrayIndex] = 1; }
else if (BitPos == 2) { TerrainPreviewData[ImageBaseArrayIndex] = 3; }
else if (BitPos == 3) { TerrainPreviewData[ImageBaseArrayIndex] = 7; }
else if (BitPos == 4) { TerrainPreviewData[ImageBaseArrayIndex] = 15; }
else if (BitPos == 5) { TerrainPreviewData[ImageBaseArrayIndex] = 31; }
else if (BitPos == 6) { TerrainPreviewData[ImageBaseArrayIndex] = 63; }
else if (BitPos == 7) { TerrainPreviewData[ImageBaseArrayIndex] = 127; }
}
ByteBlock++;
}
ArrayIndex++;
}
while (ImageBaseArrayIndex < 2097152) // to fill the rest of the image as something odd to indicate incomplete areas
{
TerrainPreviewData[ImageBaseArrayIndex] = 5;
ImageBaseArrayIndex++;
}
MaxHeightFt = (double)MaxHeightPx*0.055;
MinHeightFt = (double)MinHeightPx*0.055;
// fwrite(&TerrainPreviewData, 1, 2097152, FileHandle); // writes the entire output image data // causes stack overflow
fclose(FileHandle);
// prints textual results with a printf statement
}
When the function gets to the first and second if statements in the "while (ByteBlock < 16)" part, I get an unhandled exception notice saying of stack overflow. I don't know about the else though. The other two instructions work just fine and there's no infinite loop encountered. The other while loop where I fill the rest of the array's values to 5, near the bottom, works just fine, but when I try writing this data, I get that stack overflow case again and it's not writing any of the image data. It's writing the file head and info head just fine and I can see it in my hex editor as I expected.