Heres the class to give you a bigger picture
Code:
#ifndef TERRAGENFILE_H
#define TERRAGENFILE_H
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
enum FileError
{
FILE_NO_ERROR,
FILE_TYPE_MISMATCH,
FILE_READ_ERROR
};
class TerHeader
{
friend class TerragenFile;
friend std::ostream& operator<<(std::ostream& out, TerragenFile file);
char title[9];
char type[8];
short size;
short int xpts;
short int ypts;
float xyzScal[3];
float crad;
unsigned int crvm;
short int heightScale;
short int baseHeight;
};
class TerragenFile
{
friend std::ostream& operator<<(std::ostream& out, TerragenFile file);
public:
TerragenFile();
~TerragenFile();
FileError load(const char* filename);
void release();
void printHeights(std::ostream& out=std::cout) const;
private:
TerHeader header;
short int* elevations;
};
std::ostream& operator<<(std::ostream& out, TerragenFile file);
implementation
Code:
#include "TerragenFile.h"
using std::endl;
using std::ifstream;
using std::string;
using std::setw;
TerragenFile::TerragenFile(): elevations(NULL){ }
TerragenFile::~TerragenFile(){ release(); }
FileError TerragenFile::load(const char* filename)
{
//set the null string for the titles
ifstream file(filename);
//error reading the file
if(!file)
return FILE_NO_ERROR;
//read the header, if the first string is not "TERRAGEN" throw error
header.title[8] = header.type[7] = '\0';
file.read(header.title, 8);
file.read(header.type, 7);
if(header.title != string("TERRAGEN"))
return FILE_TYPE_MISMATCH;
//seek to the size and read
file.ignore(5);
file.read((char*)&header.size, 2);
//seek to xpts and read
file.ignore(6);
file.read((char*)&header.xpts, 2);
//seek to ypts and read
file.ignore(6);
file.read((char*)&header.ypts, 2);
elevations = new short int[header.xpts * header.ypts];
//seek to scal and read
file.ignore(6);
file.read((char*)&header.xyzScal[0], 4);
file.read((char*)&header.xyzScal[1], 4);
file.read((char*)&header.xyzScal[2], 4);
//seek to CRAD and read
file.ignore(4);
file.read((char*)&header.crad, 4);
//seek to CRVM and read
file.ignore(4);
file.read((char*)&header.crvm, 4);
//seek to ALTW and read height scale and bae height
file.ignore(4);
file.read((char*)&header.heightScale, 2);
file.read((char*)&header.baseHeight, 2);
short int a = header.baseHeight;
short int b = header.heightScale;
//reads in and calculates header data
for(int y = 0; y < header.ypts; ++y)
{
for(int x = 0; x < header.xpts; ++x)
{
unsigned short heightA = 0;
unsigned short heightB = 0;
file.read((char*)&heightA, 1);
file.read((char*)&heightB, 1);
short int result = (heightA << 8) | heightB;
short int calcHeight = a + result * b / 65536;
elevations[(y * header.xpts) + x] = calcHeight;
}
}
file.close();
return FILE_NO_ERROR;
}
void TerragenFile::release()
{
delete [] elevations;
}
void TerragenFile::printHeights(std::ostream& out) const
{
//reads in and calculates header data
for(int y = 0; y < header.ypts; ++y)
{
for(int x = 0; x < header.xpts; ++x)
out << elevations[(y * header.xpts) + x] << setw(3);
out << std::endl;
}
}
std::ostream& operator<<(std::ostream& out, TerragenFile file)
{
out << file.header.title << " : " << file.header.type << endl;
out << "SIZE = " << file.header.size << endl;
out << "XPTS = " << file.header.xpts << endl;
out << "YPTS = " << file.header.ypts << endl;
out << "XSCAL = " << file.header.xyzScal[0] << endl;
out << "ySCAL = " << file.header.xyzScal[1] << endl;
out << "zSCAL = " << file.header.xyzScal[2] << endl;
out << "CRAD = " << file.header.crad << endl;
out << "CRVM = " << file.header.crvm << endl;
return out;
}