ieglib.c 12.5 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
#include <stdio.h>
2
#include <stdlib.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
3 4 5 6 7 8 9 10
#include <string.h>
#include <ctype.h>

#include "dmemory.h"
#include "ieg.h"
#include "error.h"
#include "file.h"
#include "binary.h"
11
#include "exse.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
12 13 14
#include "swap.h"


Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
static int initIegLib      = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
16 17 18
static int iegDefaultDprec = 0;


19
// A version string.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
20
#undef  LIBVERSION
21
#define LIBVERSION      1.4.2
Uwe Schulzweida's avatar
Uwe Schulzweida committed
22 23
#define XSTRING(x)	#x
#define STRING(x)	XSTRING(x)
24
static const char ieg_libvers[] = STRING(LIBVERSION);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
25 26 27

const char *iegLibraryVersion(void)
{
28
  return ieg_libvers;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29 30 31
}


32
static int IEG_Debug = 0;    // If set to 1, debugging
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33

34 35
static
void iegLibInit(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
{
Oliver Heidmann's avatar
Oliver Heidmann committed
37
  const char *envName = "IEG_PRECISION";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38

39
  char *envString = getenv(envName);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
40 41
  if ( envString )
    {
42 43
      int nrun = (strlen(envString) == 2) ? 1 : 2;
      int pos = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
44 45 46 47 48 49 50 51
      while ( nrun-- )
	{
	  switch ( tolower((int) envString[pos]) )
	    {
	    case 'r':
	      {
		switch ( (int) envString[pos+1] )
		  {
52 53
		  case '4': iegDefaultDprec = EXSE_SINGLE_PRECISION; break;
		  case '8': iegDefaultDprec = EXSE_DOUBLE_PRECISION; break;
54
		  default: Message("Invalid digit in %s: %s", envName, envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
		  }
56
		break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57 58
	      }
	    default:
59 60 61 62 63
              {
                Message("Invalid character in %s: %s", envName, envString);
                break;
              }
            }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
64 65 66 67 68 69 70 71 72 73
	  pos += 2;
	}
    }

  initIegLib = 1;
}


void iegDebug(int debug)
{
74
  if (debug) Message("debug level %d", debug);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75 76 77
  IEG_Debug = debug;
}

78
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
void iegInit(iegrec_t *iegp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80 81 82 83 84 85 86 87
{
  iegp->checked    = 0;
  iegp->byteswap   = 0;
  iegp->dprec      = 0;
  iegp->refval     = 0;
  iegp->datasize   = 0;
  iegp->buffersize = 0;
  iegp->buffer     = NULL;
88 89
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
90

91
void iegInitMem(void *ieg)
92
{
93
  iegrec_t *iegp = (iegrec_t *) ieg;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94 95 96 97 98 99
  memset(iegp->ipdb, 0, sizeof(iegp->ipdb));
  memset(iegp->igdb, 0, sizeof(iegp->igdb));
  memset(iegp->vct,  0, sizeof(iegp->vct));
}


100
void *iegNew(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
101 102 103
{
  if ( ! initIegLib ) iegLibInit();

104
  iegrec_t *iegp = (iegrec_t *) Malloc(sizeof(iegrec_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
  iegInit(iegp);
106
  iegInitMem(iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
107

108
  return (void*)iegp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
109 110 111
}


112
void iegDelete(void *ieg)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
113
{
114 115
  iegrec_t *iegp = (iegrec_t *) ieg;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
116 117
  if ( iegp )
    {
118 119
      if ( iegp->buffer ) Free(iegp->buffer);
      Free(iegp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
120 121 122 123 124 125 126 127
    }
}


int iegCheckFiletype(int fileID, int *swap)
{
  size_t data = 0;
  size_t dimx = 0, dimy = 0;
128
  size_t fact = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
129 130
  unsigned char buffer[1048], *pbuf;

131
  if ( fileRead(fileID, buffer, 4) != 4 ) return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132

133 134
  const size_t blocklen  = get_UINT32(buffer);
  const size_t sblocklen = get_SUINT32(buffer);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
135

Uwe Schulzweida's avatar
Uwe Schulzweida committed
136
  if ( IEG_Debug ) Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137

138
  // clang-format off
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139 140 141 142
  if ( blocklen == 636 || blocklen == 640 )
    {
     *swap = 0;
      fact = 4;
143
      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
144 145 146 147 148 149 150 151
      pbuf = buffer+(37+4)*4;    dimx = (size_t) get_UINT32(pbuf);
      pbuf = buffer+(37+5)*4;    dimy = (size_t) get_UINT32(pbuf);
      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
    }
  else if ( blocklen == 1040 || blocklen == 1036 )
    {
     *swap = 0;
      fact = 8;
152
      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
153 154 155 156 157 158 159 160
      pbuf = buffer+(37+4)*4;    dimx = (size_t) get_UINT32(pbuf);
      pbuf = buffer+(37+5)*4;    dimy = (size_t) get_UINT32(pbuf);
      pbuf = buffer+blocklen+4;  data = (size_t) get_UINT32(pbuf);
    }
  else if ( sblocklen == 636 || sblocklen == 640 )
    {
     *swap = 1;
      fact = 4;
161
      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162 163 164 165 166 167 168 169
      pbuf = buffer+(37+4)*4;     dimx = (size_t) get_SUINT32(pbuf);
      pbuf = buffer+(37+5)*4;     dimy = (size_t) get_SUINT32(pbuf);
      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
    }
  else if ( sblocklen == 1040 || sblocklen == 1036 )
    {
     *swap = 1;
      fact = 8;
170
      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
171 172 173 174
      pbuf = buffer+(37+4)*4;     dimx = (size_t) get_SUINT32(pbuf);
      pbuf = buffer+(37+5)*4;     dimy = (size_t) get_SUINT32(pbuf);
      pbuf = buffer+sblocklen+4;  data = (size_t) get_SUINT32(pbuf);
    }
175
  // clang-format on
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176 177 178 179 180

  fileRewind(fileID);

  if ( IEG_Debug )
    {
181 182
      Message("swap = %d fact = %d", *swap, fact);
      Message("dimx = %lu dimy = %lu data = %lu", dimx, dimy, data);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183 184
    }

185
  const int found = data && (dimx*dimy*fact == data || dimx*dimy*8 == data);
186
  return found;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187 188 189
}


190
void iegCopyMeta(void *dieg, void *sieg)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
191
{
192 193 194
  iegrec_t *diegp = (iegrec_t *) dieg;
  iegrec_t *siegp = (iegrec_t *) sieg;

195
  // diegp->byteswap = siegp->byteswap;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
196 197 198 199 200 201 202 203
  diegp->dprec    = siegp->dprec;
  diegp->refval   = siegp->refval;

  memcpy(diegp->ipdb, siegp->ipdb, sizeof(siegp->ipdb));
  memcpy(diegp->igdb, siegp->igdb, sizeof(siegp->igdb));
  memcpy(diegp->vct,  siegp->vct,  sizeof(siegp->vct));
}

204 205
static
int iegInqData(void *ieg, int prec, void *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
206
{
207
  iegrec_t *iegp = (iegrec_t *) ieg;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
  int ierr = 0;
209 210
  const int byteswap = iegp->byteswap;
  const size_t datasize = iegp->datasize;
211
  void *buffer = iegp->buffer;
212
  const int dprec = iegp->dprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213 214 215

  switch ( dprec )
    {
216
    case EXSE_SINGLE_PRECISION:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
217
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
	if ( sizeof(FLT32) == 4 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
219 220 221 222
	  {
	    if ( byteswap ) swap4byte(buffer, datasize);

	    if ( dprec == prec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
	      memcpy(data, buffer, datasize*sizeof(FLT32));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
	    else
225
              {
Oliver Heidmann's avatar
Oliver Heidmann committed
226 227
                const float *restrict p = (float *)buffer;
                double *restrict q = (double *)data;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
                for (size_t i = 0; i < datasize; i++) q[i] = p[i];
229
              }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
230 231 232
	  }
	else
	  {
233
	    Error("not implemented for %d byte float", sizeof(FLT32));
234
	  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235 236
	break;
      }
237
    case EXSE_DOUBLE_PRECISION:
238
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
239
	if ( sizeof(FLT64) == 8 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240 241 242 243
	  {
	    if ( byteswap ) swap8byte(buffer, datasize);

	    if ( dprec == prec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
	      memcpy(data, buffer, datasize*sizeof(FLT64));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
	    else
246
              {
Oliver Heidmann's avatar
Oliver Heidmann committed
247 248
                const double *restrict p = (double *)buffer;
                float *restrict q = (float *)data;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
249
                for (size_t i = 0; i < datasize; i++) q[i] = (float)p[i];
250
              }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251 252 253
	  }
	else
	  {
254
	    Error("not implemented for %d byte float", sizeof(FLT64));
255
	  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
	break;
257
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258 259
    default:
      {
260
	Error("unexpected data precision %d", dprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262 263 264
      }
    }

265
  return ierr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
266 267 268
}


269
int iegInqDataSP(void *ieg, float *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270
{
271
  return iegInqData(ieg, EXSE_SINGLE_PRECISION, (void *) data);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272 273 274
}


275
int iegInqDataDP(void *ieg, double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276
{
277
  return iegInqData(ieg, EXSE_DOUBLE_PRECISION, (void *) data);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278 279 280
}


Thomas Jahns's avatar
Thomas Jahns committed
281 282
static int
iegDefData(iegrec_t *iegp, int prec, const void *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283
{
284
  int dprec = iegDefaultDprec ? iegDefaultDprec : iegp->dprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
  iegp->dprec = dprec ? dprec : prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
286

287 288
  const size_t datasize = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
  const size_t blocklen = datasize * (size_t)dprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
289 290 291

  iegp->datasize = datasize;

292
  if ( iegp->buffersize != blocklen )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
293
    {
294 295
      iegp->buffersize = blocklen;
      iegp->buffer = Realloc(iegp->buffer, iegp->buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
296 297 298 299
    }

  switch ( dprec )
    {
300
    case EXSE_SINGLE_PRECISION:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
301 302
      {
	if ( dprec == prec )
303
	  memcpy(iegp->buffer, data, datasize*sizeof(FLT32));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
	else
305 306
          {
            const double *restrict p = (const double *)data;
307
            float *restrict q = (float *)iegp->buffer;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308
            for (size_t i = 0; i < datasize; i++) q[i] = (float)p[i];
309
          }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
310 311
	break;
      }
312
    case EXSE_DOUBLE_PRECISION:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
313 314
      {
	if ( dprec == prec )
315
	  memcpy(iegp->buffer, data, datasize*sizeof(FLT64));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
316
	else
317 318
          {
            const float *restrict p = (const float *)data;
319
            double *restrict q = (double *)iegp->buffer;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
320
            for ( size_t i = 0; i < datasize; i++) q[i] = p[i];
321
          }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322 323 324 325
	break;
      }
    default:
      {
326
	Error("unexpected data precision %d", dprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
328 329 330
      }
    }

331
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332 333 334
}


335
int iegDefDataSP(void *ieg, const float *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
{
Thomas Jahns's avatar
Thomas Jahns committed
337
  return iegDefData((iegrec_t *)ieg, EXSE_SINGLE_PRECISION, (void *) data);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338 339 340
}


341
int iegDefDataDP(void *ieg, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
{
Thomas Jahns's avatar
Thomas Jahns committed
343
  return iegDefData((iegrec_t *)ieg, EXSE_DOUBLE_PRECISION, (void *) data);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
344 345 346
}


347
int iegRead(int fileID, void *ieg)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
{
349
  iegrec_t *iegp = (iegrec_t *) ieg;
Thomas Jahns's avatar
Thomas Jahns committed
350
  union { double d[200]; float f[200]; int32_t i32[200]; } buf;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351 352 353

  if ( ! iegp->checked )
    {
354
      const int status = iegCheckFiletype(fileID, &iegp->byteswap);
355
      if ( status == 0 ) Error("Not a IEG file!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356 357 358
      iegp->checked = 1;
    }

359
  const int byteswap = iegp->byteswap;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360

361
  // read header record
362
  size_t blocklen = binReadF77Block(fileID, byteswap);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
363

364
  if ( fileEOF(fileID) ) return -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365

366
  if ( IEG_Debug ) Message("blocklen = %lu", blocklen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
367

Thomas Jahns's avatar
Thomas Jahns committed
368
  int dprec = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369 370 371 372 373 374
  if ( blocklen == 636 || blocklen == 640 )
    dprec = 4;
  else if ( blocklen == 1040 || blocklen == 1036 )
    dprec = 8;
  else
    {
375
      Warning("unexpecteted header size %d!", (int) blocklen);
376
      return -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
377 378 379 380
    }

  iegp->dprec = dprec;

Thomas Jahns's avatar
Thomas Jahns committed
381
  binReadInt32(fileID, byteswap, 37, buf.i32);
382
  for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = (int)buf.i32[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
383

Thomas Jahns's avatar
Thomas Jahns committed
384
  binReadInt32(fileID, byteswap, 18, buf.i32);
385
  for ( int i = 0; i < 18; i++ ) iegp->igdb[i] = (int)buf.i32[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386 387 388

  if ( blocklen == 636 || blocklen == 1036 )
    {
Thomas Jahns's avatar
Thomas Jahns committed
389 390 391
      fileRead(fileID, buf.f, 4);
      if ( byteswap ) swap4byte(buf.f, 1);
      iegp->refval = (double)buf.f[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392 393 394
    }
  else
    {
Thomas Jahns's avatar
Thomas Jahns committed
395 396 397
      fileRead(fileID, buf.d, 8);
      if ( byteswap ) swap8byte(buf.d, 1);
      iegp->refval = (double)buf.d[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
398 399
    }

Thomas Jahns's avatar
Thomas Jahns committed
400
  binReadInt32(fileID, byteswap, 3, buf.i32);
401
  for ( int i = 0; i < 3; i++ ) iegp->igdb[18+i] = (int)buf.i32[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402

403
  if ( dprec == EXSE_SINGLE_PRECISION )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
    {
Thomas Jahns's avatar
Thomas Jahns committed
405 406
      fileRead(fileID, buf.f, 400);
      if ( byteswap ) swap4byte(buf.f, 100);
407
      for ( int i = 0; i < 100; i++ ) iegp->vct[i] = (double)buf.f[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408 409 410
    }
  else
    {
Thomas Jahns's avatar
Thomas Jahns committed
411 412
      fileRead(fileID, buf.d, 800);
      if ( byteswap ) swap8byte(buf.d, 100);
413
      for ( int i = 0; i < 100; i++ ) iegp->vct[i] = buf.d[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
    }
415

416
  size_t blocklen2 = binReadF77Block(fileID, byteswap);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
417 418 419

  if ( blocklen2 != blocklen )
    {
420
      Warning("header blocklen differ!");
421
      return -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
422 423
    }

424
  iegp->datasize = (size_t)IEG_G_NumLon(iegp->igdb) * (size_t)IEG_G_NumLat(iegp->igdb);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425

426
  if ( IEG_Debug ) Message("datasize = %zu", iegp->datasize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427 428 429

  blocklen = binReadF77Block(fileID, byteswap);

Thomas Jahns's avatar
Thomas Jahns committed
430
  if ( iegp->buffersize < blocklen )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
    {
432
      iegp->buffer = Realloc(iegp->buffer, blocklen);
Thomas Jahns's avatar
Thomas Jahns committed
433
      iegp->buffersize = blocklen;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434 435
    }

436
  if ( dprec != (int) (blocklen/iegp->datasize) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
437
    {
438
      Warning("data precision differ! (h = %d; d = %d)", (int) dprec, (int) (blocklen/iegp->datasize));
439
      return -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
440 441
    }

442
  fileRead(fileID, iegp->buffer, blocklen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
443 444 445 446 447

  blocklen2 = binReadF77Block(fileID, byteswap);

  if ( blocklen2 != blocklen )
    {
448
      Warning("data blocklen differ!");
449
      return -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
450 451
    }

452
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453 454 455
}


456
int iegWrite(int fileID, void *ieg)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
{
458
  iegrec_t *iegp = (iegrec_t *) ieg;
Thomas Jahns's avatar
Thomas Jahns committed
459
  union { INT32 i32[200]; float fvct[100]; } buf;
460 461
  const int dprec  = iegp->dprec;
  const int byteswap = iegp->byteswap;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
462

463
  // write header record
Thomas Jahns's avatar
Thomas Jahns committed
464
  size_t blocklen = ( dprec == EXSE_SINGLE_PRECISION ) ? 636 : 1040;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465 466 467

  binWriteF77Block(fileID, byteswap, blocklen);

468
  for ( int i = 0; i < 37; i++ ) buf.i32[i] = (INT32) iegp->ipdb[i];
Thomas Jahns's avatar
Thomas Jahns committed
469
  binWriteInt32(fileID, byteswap, 37, buf.i32);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470

471
  for ( int i = 0; i < 18; i++ ) buf.i32[i] = (INT32) iegp->igdb[i];
Thomas Jahns's avatar
Thomas Jahns committed
472
  binWriteInt32(fileID, byteswap, 18, buf.i32);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
473

Thomas Jahns's avatar
Thomas Jahns committed
474 475
  FLT64 refval = (FLT64)iegp->refval;
  FLT32 refvalf = (FLT32)iegp->refval;
476
  if ( dprec == EXSE_SINGLE_PRECISION )
Thomas Jahns's avatar
Thomas Jahns committed
477
    binWriteFlt32(fileID, byteswap, 1, &refvalf);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
478
  else
Thomas Jahns's avatar
Thomas Jahns committed
479
    binWriteFlt64(fileID, byteswap, 1, &refval);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
480

481
  for ( int i = 0; i < 3; i++ ) buf.i32[i] = (INT32) iegp->igdb[18+i];
Thomas Jahns's avatar
Thomas Jahns committed
482
  binWriteInt32(fileID, byteswap, 3, buf.i32);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
483

484
  if ( dprec == EXSE_SINGLE_PRECISION )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
485
    {
486
      for ( int i = 0; i < 100; i++ ) buf.fvct[i] = (float) iegp->vct[i];
Thomas Jahns's avatar
Thomas Jahns committed
487
      binWriteFlt32(fileID, byteswap, 100, buf.fvct);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
488 489 490
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
491
      binWriteFlt64(fileID, byteswap, 100, iegp->vct);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492
    }
493

Uwe Schulzweida's avatar
Uwe Schulzweida committed
494 495
  binWriteF77Block(fileID, byteswap, blocklen);

496 497
  iegp->datasize = (size_t)iegp->igdb[4] * (size_t)iegp->igdb[5];
  blocklen = iegp->datasize * (size_t)dprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
498 499 500 501 502

  binWriteF77Block(fileID, byteswap, blocklen);

  switch ( dprec )
    {
503
    case EXSE_SINGLE_PRECISION:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
      {
505
	binWriteFlt32(fileID, byteswap, iegp->datasize, (FLT32 *) iegp->buffer);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
506 507
	break;
      }
508
    case EXSE_DOUBLE_PRECISION:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
      {
510
	binWriteFlt64(fileID, byteswap, iegp->datasize, (FLT64 *) iegp->buffer);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
511 512 513 514
	break;
      }
    default:
      {
515
	Error("unexpected data precision %d", dprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
517 518 519 520 521
      }
    }

  binWriteF77Block(fileID, byteswap, blocklen);

522
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
}
524 525 526 527 528 529 530 531 532
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */