extralib.c 12.2 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>

#include "dmemory.h"

#include "extra.h"
#include "error.h"
#include "file.h"
#include "binary.h"
16
#include "stream_fcommon.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17
18
19
#include "swap.h"


20
21
22
enum {
  EXT_HEADER_LEN = 4,
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
23
24


Uwe Schulzweida's avatar
Uwe Schulzweida committed
25
26
27
static int initExtLib       = 0;
static int extDefaultPrec   = 0;
static int extDefaultNumber = EXT_REAL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
29
30
31
32
33
34


/*
 * A version string.
 */

#undef  LIBVERSION
35
#define LIBVERSION      1.3.2
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37
#define XSTRING(x)	#x
#define STRING(x)	XSTRING(x)
38
static const char ext_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__ ;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
40
41
42
43
44
45

const char *extLibraryVersion(void)
{
  return (ext_libvers);
}


46
static int EXT_Debug = 0;    /* If set to 1, debugging */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
47
48
49
50
51
52
53


void extDebug(int debug)
{
  EXT_Debug = debug;

  if ( EXT_Debug )
54
    Message("debug level %d", debug);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
56
57
}


58
static void extLibInit()
Uwe Schulzweida's avatar
Uwe Schulzweida committed
59
60
{
  char *envString;
Oliver Heidmann's avatar
Oliver Heidmann committed
61
  const char *envName = "EXT_PRECISION";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
63
64
65
66


  envString = getenv(envName);
  if ( envString )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67
      int pos = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
68

Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
      if ( strlen(envString) == 2  )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
70
71
72
	{
	  switch ( tolower((int) envString[pos]) )
	    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
	    case 'r':
Uwe Schulzweida's avatar
Uwe Schulzweida committed
74
	      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
		extDefaultNumber = EXT_REAL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
76
77
		switch ( (int) envString[pos+1] )
		  {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
78
79
		  case '4': extDefaultPrec = SINGLE_PRECISION; break;
		  case '8': extDefaultPrec = DOUBLE_PRECISION; break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
		  default:
81
		    Message("Invalid digit in %s: %s", envName, envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
		  }
83
		break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
	      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
	    case 'c':
Uwe Schulzweida's avatar
Uwe Schulzweida committed
86
	      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
87
		extDefaultNumber = EXT_COMP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
88
89
		switch ( (int) envString[pos+1] )
		  {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
90
91
		  case '4': extDefaultPrec = SINGLE_PRECISION; break;
		  case '8': extDefaultPrec = DOUBLE_PRECISION; break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
		  default:
93
		    Message("Invalid digit in %s: %s", envName, envString);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
		  }
95
		break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
	      }
	    default:
98
99
100
101
102
              {
                Message("Invalid character in %s: %s", envName, envString);
                break;
              }
            }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
104
105
106
107
108
	}
    }

  initExtLib = 1;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
109
110
static
void extInit(extrec_t *extp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
{
  extp->checked    = 0;
  extp->byteswap   = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
115
  extp->prec       = 0;
  extp->number     = extDefaultNumber;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
116
117
118
119
120
121
  extp->datasize   = 0;
  extp->buffersize = 0;
  extp->buffer     = NULL;
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
122
void *extNew(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
123
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
124
  extrec_t *extp;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125
126
127

  if ( ! initExtLib ) extLibInit();

Uwe Schulzweida's avatar
Uwe Schulzweida committed
128
  extp = (extrec_t *) malloc(sizeof(extrec_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
129
130
131

  extInit(extp);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
  return ((void*)extp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
133
134
135
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
136
void extDelete(void *ext)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
138
  extrec_t *extp = (extrec_t *) ext;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
140
141
142
143
144
145
146
147
148
149

  if ( extp )
    {
      if ( extp->buffer ) free(extp->buffer);
      free(extp);
    }
}


int extCheckFiletype(int fileID, int *swap)
{
150
  size_t blocklen = 0, fact = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
151
152
153
  size_t sblocklen = 0;
  size_t data =  0;
  size_t dimxy = 0;
154
  int found = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
155
156
157
158
159
160
161
162
  unsigned char buffer[40], *pbuf;

  if ( fileRead(fileID, buffer, 4) != 4 ) return (found);

  blocklen  = (size_t) get_UINT32(buffer);
  sblocklen = (size_t) get_SUINT32(buffer);

  if ( EXT_Debug )
163
    Message("blocklen = %d sblocklen = %d", blocklen, sblocklen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

  if ( blocklen == 16 )
    {
     *swap = 0;
      fact = blocklen/4;
      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
      pbuf = buffer+3*fact;      dimxy = (size_t) get_UINT32(pbuf);
      pbuf = buffer+blocklen+4;  data  = (size_t) get_UINT32(pbuf);
    }
  else if ( blocklen == 32 )
    {
     *swap = 0;
      fact = blocklen/4;
      if ( fileRead(fileID, buffer, blocklen+8) != blocklen+8 ) return (found);
      pbuf = buffer+3*fact;      dimxy = (size_t) get_UINT64(pbuf);
      pbuf = buffer+blocklen+4;  data  = (size_t) get_UINT32(pbuf);
    }
  else if ( sblocklen == 16 )
    {
     *swap = 1;
      fact = sblocklen/4;
      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
      pbuf = buffer+3*fact;       dimxy = (size_t) get_SUINT32(pbuf);
      pbuf = buffer+sblocklen+4;  data  = (size_t) get_SUINT32(pbuf);
    }
  else if ( sblocklen == 32 )
    {
     *swap = 1;
      fact = sblocklen/4;
      if ( fileRead(fileID, buffer, sblocklen+8) != sblocklen+8 ) return (found);
      pbuf = buffer+3*fact;       dimxy = (size_t) get_SUINT64(pbuf);
      pbuf = buffer+sblocklen+4;  data  = (size_t) get_SUINT32(pbuf);
    }

  fileRewind(fileID);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
200
201
  if      ( data && dimxy*fact   == data ) found = 1;
  else if ( data && dimxy*fact*2 == data ) found = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202
203
204

  if ( EXT_Debug )
    {
205
206
      Message("swap = %d fact = %d", *swap, fact);
      Message("dimxy = %lu data = %lu", dimxy, data);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
207
208
209
210
211
212
    }

  return (found);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
int extInqHeader(void *ext, int *header)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
  extrec_t *extp = (extrec_t *) ext;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
217
218
219
  size_t i;

  for ( i = 0; i < EXT_HEADER_LEN; i++ )
    header[i] = extp->header[i];
220

221
  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224
225
226

  return (0);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
int extDefHeader(void *ext, const int *header)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
  extrec_t *extp = (extrec_t *) ext;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
230
231
232
233
  size_t i;

  for ( i = 0; i < EXT_HEADER_LEN; i++ )
    extp->header[i] = header[i];
234

235
  extp->datasize = (size_t)header[3];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
  if ( extp->number == EXT_COMP ) extp->datasize *= 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237

238
  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
239
240
241
242
243

  return (0);
}


244
static int extInqData(extrec_t *extp, int prec, void *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
246
247
248
{
  size_t datasize;
  size_t i;
  int ierr = 0;
249
  int rprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
250
251
252
253
  void *buffer;
  int byteswap = extp->byteswap;

  datasize = extp->datasize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
255
  buffer   = extp->buffer;
  rprec    = extp->prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256

Uwe Schulzweida's avatar
Uwe Schulzweida committed
257
  switch ( rprec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
259
260
    {
    case SINGLE_PRECISION:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
261
	if ( sizeof(FLT32) == 4 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262
263
264
	  {
	    if ( byteswap ) swap4byte(buffer, datasize);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
	    if ( rprec == prec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
266
	      memcpy(data, buffer, datasize*sizeof(FLT32));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
	    else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
	      for ( i = 0; i < datasize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
269
270
271
272
		((double *) data)[i] = (double) ((float *) buffer)[i];
	  }
	else
	  {
273
	    Error("not implemented for %d byte float", sizeof(FLT32));
274
	  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
276
277
	break;
      }
    case DOUBLE_PRECISION:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
	if ( sizeof(FLT64) == 8 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
280
281
	  {
	    if ( byteswap ) swap8byte(buffer, datasize);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
282
	    if ( rprec == prec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
283
	      memcpy(data, buffer, datasize*sizeof(FLT64));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
	    else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
	      for ( i = 0; i < datasize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
286
287
288
289
		((float *) data)[i] = (float) ((double *) buffer)[i];
	  }
	else
	  {
290
	    Error("not implemented for %d byte float", sizeof(FLT64));
291
	  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
293
294
	break;
    default:
      {
295
	Error("unexpected data precision %d", rprec);
296
	break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
297
298
299
300
301
302
303
      }
    }

  return (ierr);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
int extInqDataSP(void *ext, float *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305
{
Oliver Heidmann's avatar
Oliver Heidmann committed
306
  return (extInqData((extrec_t *)ext, SINGLE_PRECISION, (void *) data));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
307
308
309
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
310
int extInqDataDP(void *ext, double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
{
Oliver Heidmann's avatar
Oliver Heidmann committed
312
  return (extInqData((extrec_t *)ext, DOUBLE_PRECISION, (void *) data));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
316
int extDefData(void *ext, int prec, const void *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
317
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
318
  extrec_t *extp = (extrec_t *) ext;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
320
321
322
  size_t datasize;
  size_t blocklen;
  size_t buffersize;
  size_t i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
  int rprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324
325
326
  int *header;
  void *buffer;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
327
328
  if ( extDefaultPrec ) rprec = extDefaultPrec;
  else                  rprec = extp->prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329

Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
  if ( ! rprec ) rprec = prec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331

Uwe Schulzweida's avatar
Uwe Schulzweida committed
332
  extp->prec = rprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333
334
335

  header = extp->header;

336
  datasize = (size_t)header[3];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
337
  if ( extp->number == EXT_COMP ) datasize *= 2;
338
  blocklen = datasize * (size_t)rprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

  extp->datasize = datasize;

  buffersize = extp->buffersize;

  if ( buffersize != blocklen )
    {
      buffersize = blocklen;
      buffer = extp->buffer;
      buffer = realloc(buffer, buffersize);
      extp->buffer = buffer;
      extp->buffersize = buffersize;
    }
  else
    buffer = extp->buffer;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
  switch ( rprec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
357
358
    {
    case SINGLE_PRECISION:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
359
	if ( rprec == prec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
	  memcpy(buffer, data, datasize*sizeof(FLT32));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362
363
364
365
366
367
368
	else
	  for (i = 0; i < datasize; i++)
	    ((float *) buffer)[i] = (float) ((double *) data)[i];

	break;
      }
    case DOUBLE_PRECISION:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
	if ( rprec == prec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
	  memcpy(buffer, data, datasize*sizeof(FLT64));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
371
372
373
374
375
376
377
378
	else
	  for (i = 0; i < datasize; i++)
	    ((double *) buffer)[i] = (double) ((float *) data)[i];

	break;
      }
    default:
      {
379
	Error("unexpected data precision %d", rprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
380
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
381
382
383
384
385
386
387
      }
    }

  return (0);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
int extDefDataSP(void *ext, const float *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
  return (extDefData(ext, SINGLE_PRECISION, (void *) data));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
391
392
393
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
394
int extDefDataDP(void *ext, const double *data)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
396
  return (extDefData(ext, DOUBLE_PRECISION, (void *) data));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397
398
399
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
int extRead(int fileID, void *ext)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402
  extrec_t *extp = (extrec_t *) ext;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405
406
407
408
409
410
411
  size_t blocklen, blocklen2;
  size_t i;
  void *buffer;
  int byteswap;
  int status;

  if ( ! extp->checked )
    {
      status = extCheckFiletype(fileID, &extp->byteswap);
412
      if ( status == 0 ) Error("Not a EXTRA file!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414
415
416
417
418
419
420
421
422
423
      extp->checked = 1;
    }

  byteswap = extp->byteswap;

  /* read header record */
  blocklen = binReadF77Block(fileID, byteswap);

  if ( fileEOF(fileID) ) return (-1);

  if ( EXT_Debug )
424
    Message("blocklen = %lu", blocklen);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
425

426
  size_t hprec = blocklen / EXT_HEADER_LEN;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
427

428
  extp->prec = (int)hprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
430
431
432
433

  switch ( hprec )
    {
    case SINGLE_PRECISION:
      {
434
435
        INT32 tempheader[4];
	binReadInt32(fileID, byteswap, EXT_HEADER_LEN, tempheader);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
437

	for ( i = 0; i < EXT_HEADER_LEN; i++ )
438
          extp->header[i] = (int)tempheader[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
440
441
442
443

	break;
      }
    case DOUBLE_PRECISION:
      {
444
445
        INT64 tempheader[4];
	binReadInt64(fileID, byteswap, EXT_HEADER_LEN, tempheader);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
447

	for ( i = 0; i < EXT_HEADER_LEN; i++ )
448
          extp->header[i] = (int)tempheader[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
449
450
451
452
453

	break;
      }
    default:
      {
454
	Error("Unexpected header precision %d", hprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
457
458
459
460
461
462
      }
    }

  blocklen2 = binReadF77Block(fileID, byteswap);

  if ( blocklen2 != blocklen )
    {
463
464
      Warning("Header blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
      if ( blocklen2 != 0 ) return (-1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
466
    }

467
  extp->datasize = (size_t)extp->header[3];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
468

469
  if ( EXT_Debug ) Message("datasize = %lu", extp->datasize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470
471
472

  blocklen = binReadF77Block(fileID, byteswap);

473
  size_t buffersize = (size_t)extp->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
474

475
  if ( buffersize < blocklen )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
476
477
478
479
480
481
482
483
484
485
    {
      buffersize = blocklen;
      buffer = extp->buffer;
      buffer = realloc(buffer, buffersize);
      extp->buffer = buffer;
      extp->buffersize = buffersize;
    }
  else
    buffer = extp->buffer;

486
  size_t dprec = blocklen / extp->datasize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
487

Uwe Schulzweida's avatar
Uwe Schulzweida committed
488
489
490
491
492
493
494
495
496
497
  if ( dprec == hprec )
    {
      extp->number = EXT_REAL;
    }
  else if ( dprec == 2*hprec )
    {
      dprec /= 2;
      extp->datasize *= 2;
      extp->number = EXT_COMP;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
498
499
500

  if ( dprec != SINGLE_PRECISION && dprec != DOUBLE_PRECISION )
    {
501
      Warning("Unexpected data precision %d", dprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
503
504
505
506
507
508
509
510
      return (-1);
    }

  fileRead(fileID, buffer, blocklen);

  blocklen2 = binReadF77Block(fileID, byteswap);

  if ( blocklen2 != blocklen )
    {
511
512
      Warning("Data blocklen differ (blocklen1=%d; blocklen2=%d)!", blocklen, blocklen2);
      if ( blocklen2 != 0 ) return (-1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
513
514
515
516
517
518
    }

  return (0);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
519
int extWrite(int fileID, void *ext)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
521
  extrec_t *extp = (extrec_t *) ext;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523
524
  size_t datasize;
  size_t blocklen;
  size_t i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
  int rprec, number;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
527
528
529
530
531
  char tempheader[32];
  int *header;
  void *buffer;
  int byteswap = extp->byteswap;


Uwe Schulzweida's avatar
Uwe Schulzweida committed
532
533
  rprec  = extp->prec;
  number = extp->number;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
  header = extp->header;

  /* write header record */
537
  blocklen = EXT_HEADER_LEN * (size_t)rprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
539
540

  binWriteF77Block(fileID, byteswap, blocklen);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
  switch ( rprec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
    {
    case SINGLE_PRECISION:
      {
	for (i = 0; i < EXT_HEADER_LEN; i++)
          ((INT32 *) tempheader)[i] = (INT32) header[i];

	binWriteInt32(fileID, byteswap, EXT_HEADER_LEN, (INT32 *) tempheader);

	break;
      }
    case DOUBLE_PRECISION:
      {
	for (i = 0; i < EXT_HEADER_LEN; i++)
          ((INT64 *) tempheader)[i] = (INT64) header[i];

	binWriteInt64(fileID, byteswap, EXT_HEADER_LEN, (INT64 *) tempheader);

	break;
      }
    default:
      {
563
	Error("unexpected header precision %d", rprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
564
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566
      }
    }
567

Uwe Schulzweida's avatar
Uwe Schulzweida committed
568
569
  binWriteF77Block(fileID, byteswap, blocklen);

570
  datasize = (size_t)header[3];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
571
  if ( number == EXT_COMP ) datasize *= 2;
572
  blocklen = datasize * (size_t)rprec;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
574
575
576
577
578
579

  binWriteF77Block(fileID, byteswap, blocklen);

  extp->datasize = datasize;

  buffer = extp->buffer;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
  switch ( rprec )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
582
583
    {
    case SINGLE_PRECISION:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
	binWriteFlt32(fileID, byteswap, datasize, (FLT32 *) buffer);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
586
587
588
	break;
      }
    case DOUBLE_PRECISION:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
	binWriteFlt64(fileID, byteswap, datasize, (FLT64 *) buffer);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590
591
592
593
	break;
      }
    default:
      {
594
	Error("unexpected data precision %d", rprec);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
595
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597
598
599
600
601
602
      }
    }

  binWriteF77Block(fileID, byteswap, blocklen);

  return (0);
}
603
604
605
606
607
608
609
610
611
/*
 * Local Variables:
 * c-file-style: "Java"
 * c-basic-offset: 2
 * indent-tabs-mode: nil
 * show-trailing-whitespace: t
 * require-trailing-newline: t
 * End:
 */