/** Read the header from a COMP* file and return results in the V5DStruct.
@return true = ok, false = error.
*/
boolean read_comp_header() throws IOException {
int id;
RandomAccessFile f = FileDesc;
// reset file position to start of file
f.seek(0);
// read file ID
id = f.readInt();
if (id == 0x80808080 || id == 0x80808081) {
// Older COMP5D format
int gridtimes, gridparms;
int i, j, it, iv, nl;
int gridsize;
float hgttop, hgtinc;
if (id == 0x80808080) {
// 20 vars, 300 times
gridtimes = 300;
gridparms = 20;
}
else {
// 30 vars, 400 times
gridtimes = 400;
gridparms = 30;
}
FirstGridPos = 12 * 4 + 8 * gridtimes + 4 * gridparms;
NumTimes = f.readInt();
NumVars = f.readInt();
Nr = f.readInt();
Nc = f.readInt();
nl = f.readInt();
for (i=0; i<NumVars; i++) {
Nl[i] = nl;
LowLev[i] = 0;
}
ProjArgs[0] = f.readFloat();
ProjArgs[1] = f.readFloat();
hgttop = f.readFloat();
ProjArgs[2] = f.readFloat();
ProjArgs[3] = f.readFloat();
hgtinc = f.readFloat();
VerticalSystem = 1;
VertArgs[0] = hgttop - hgtinc * (nl - 1);
VertArgs[1] = hgtinc;
// read dates and times
for (i=0; i<gridtimes; i++) {
j = f.readInt();
DateStamp[i] = v5dDaysToYYDDD(j);
}
for (i=0; i<gridtimes; i++) {
j = f.readInt();
TimeStamp[i] = v5dSecondsToHHMMSS(j);
}
// read variable names
for (i=0; i<gridparms; i++) {
char[] name = new char[4];
for (int q=0; q<4; q++) name[q] = (char) f.readByte();
// remove trailing spaces, if any
for (j=3; j>0; j--) {
if (name[j] == ' ' || name[j] == 0) name[j] = 0;
else break;
}
System.arraycopy(name, 0, VarName[i], 0, 4);
VarName[i][4] = 0;
}
gridsize = ((Nr * Nc * nl + 3) / 4) * 4;
for (i=0; i<NumVars; i++) {
GridSize[i] = 8 + gridsize;
}
SumGridSizes = (8 + gridsize) * NumVars;
// read the grids and their ga,gb values to find min and max values
for (i=0; i<NumVars; i++) {
MinVal[i] = 999999.9f;
MaxVal[i] = -999999.9f;
}
for (it=0; it<NumTimes; it++) {
for (iv=0; iv<NumVars; iv++) {
float ga, gb;
float min, max;
ga = f.readFloat();
gb = f.readFloat();
// skip ahead by gridsize bytes
f.skipBytes(gridsize);
min = -(125.0f + gb) / ga;
max = (125.0f-gb) / ga;
if (min < MinVal[iv]) MinVal[iv] = min;
if (max > MaxVal[iv]) MaxVal[iv] = max;
}
}
// done
}
else if (id == 0x80808082 || id == 0x80808083) {
// Newer COMP5D format
int gridtimes, gridsize;
int it, iv, nl, i, j;
float delta = 0f;
gridtimes = f.readInt();
NumVars = f.readInt();
NumTimes = f.readInt();
Nr = f.readInt();
Nc = f.readInt();
nl = f.readInt();
for (i=0; i<NumVars; i++) {
Nl[i] = nl;
}
ProjArgs[2] = f.readFloat();
ProjArgs[3] = f.readFloat();
// Read height and determine if equal spacing
VerticalSystem = 1;
for (i=0; i<nl; i++) {
VertArgs[i] = f.readFloat();
if (i == 1) {
delta = VertArgs[1] - VertArgs[0];
}
else if (i > 1) {
if (delta != (VertArgs[i] - VertArgs[i - 1])) {
VerticalSystem = 2;
}
}
}
if (VerticalSystem == 1) VertArgs[1] = delta;
// read variable names
for (iv=0; iv<NumVars; iv++) {
char[] name = new char[8];
for (int q=0; q<8; q++) name[q] = (char) f.readByte();
// remove trailing spaces, if any
for (j=7; j>0; j--) {
if (name[j] == ' ' || name[j] == 0) name[j] = 0;
else break;
}
System.arraycopy(name, 0, VarName[iv], 0, 8);
VarName[iv][8] = 0;
}
for (iv=0; iv<NumVars; iv++) {
MinVal[iv] = f.readFloat();
}
for (iv=0; iv<NumVars; iv++) {
MaxVal[iv] = f.readFloat();
}
for (it=0; it<gridtimes; it++) {
j = f.readInt();
TimeStamp[it] = v5dSecondsToHHMMSS(j);
}
for (it=0; it<gridtimes; it++) {
j = f.readInt();
DateStamp[it] = v5dDaysToYYDDD(j);
}
for (it=0; it<gridtimes; it++) {
float nlat;
nlat = f.readFloat();
if (it == 0) ProjArgs[0] = nlat;
}
for (it=0; it<gridtimes; it++) {
float wlon;
wlon = f.readFloat();
if (it == 0) ProjArgs[1] = wlon;
}
// calculate grid storage sizes
if (id == 0x80808082) {