stream_cgribex.c 57.8 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

5
#include <limits.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
#include <stdio.h>

#include "dmemory.h"
#include "cdi.h"
10
#include "cdi_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
11
12
13
14
#include "file.h"
#include "varscan.h"
#include "datetime.h"
#include "vlist.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
15
#include "stream_grb.h"
16
#include "stream_cgribex.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
17

Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
19
20
#if  defined  (HAVE_LIBCGRIBEX)
#  include "cgribex.h"
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21
22

typedef struct {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
23
  int param;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24
25
26
  int level1;
  int level2;
  int ltype;
27
  int tsteptype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
28
} compvar_t;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
29
30


Uwe Schulzweida's avatar
Uwe Schulzweida committed
31
#if  defined  (HAVE_LIBCGRIBEX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
int cgribexGetGridType(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
{
35
  int gridtype = GRID_GENERIC;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37
38

  switch (ISEC2_GridType)
    {
39
    case  GRIB1_GTYPE_LATLON:     { if ( ISEC2_Reduced )      break; }
40
41
42
43
44
45
46
47
48
49
    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_LONLAT;   break; }
    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;      break; }
    case  GRIB1_GTYPE_GAUSSIAN:   { if ( ISEC2_Reduced )
	                              gridtype = GRID_GAUSSIAN_REDUCED;
                         	    else
				      gridtype = GRID_GAUSSIAN;
          	                    break;
                                  }
    case  GRIB1_GTYPE_SPECTRAL:   { gridtype = GRID_SPECTRAL; break; }
    case  GRIB1_GTYPE_GME:        { gridtype = GRID_GME;      break; }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
50
51
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
52
  return gridtype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
54
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
static
56
bool cgribexGetIsRotated(int *isec2)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
57
{
58
  bool isRotated = (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT) ? true : false;
59

Uwe Schulzweida's avatar
Uwe Schulzweida committed
60
  return isRotated;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
61
62
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
int cgribexGetZaxisHasBounds(int grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
65
66
67
{
  int lbounds = 0;

68
  switch (grb_ltype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
    {
70
    case GRIB1_LTYPE_SIGMA_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71
72
    case GRIB1_LTYPE_HYBRID_LAYER:
    case GRIB1_LTYPE_LANDDEPTH_LAYER:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
74
75
76
77
78
      {
	lbounds = 1;
	break;
      }
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
  return lbounds;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
81
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
83
int cgribexGetTimeUnit(int *isec1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
{
85
  int timeunit = TUNIT_HOUR;
86
  static bool lprint = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
87
88
89

  switch ( ISEC1_TimeUnit )
    {
90
91
92
93
94
95
96
97
    case ISEC1_TABLE4_MINUTE:    timeunit = TUNIT_MINUTE;    break;
    case ISEC1_TABLE4_QUARTER:   timeunit = TUNIT_QUARTER;   break;
    case ISEC1_TABLE4_30MINUTES: timeunit = TUNIT_30MINUTES; break;
    case ISEC1_TABLE4_HOUR:      timeunit = TUNIT_HOUR;      break;
    case ISEC1_TABLE4_3HOURS:    timeunit = TUNIT_3HOURS;    break;
    case ISEC1_TABLE4_6HOURS:    timeunit = TUNIT_6HOURS;    break;
    case ISEC1_TABLE4_12HOURS:   timeunit = TUNIT_12HOURS;   break;
    case ISEC1_TABLE4_DAY:       timeunit = TUNIT_DAY;       break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
99
100
    default:
      if ( lprint )
	{
101
	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
102
	  lprint = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
103
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
104
      break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
105
106
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
  return timeunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
108
109
}

110
static
111
bool cgribexTimeIsFC(int *isec1)
112
{
113
  bool isFC = (ISEC1_TimeRange == 10 && ISEC1_TimePeriod1 == 0 && ISEC1_TimePeriod2 == 0) ? false : true;
114

Uwe Schulzweida's avatar
Uwe Schulzweida committed
115
  return isFC;
116
117
118
119
120
}

static
int cgribexGetTsteptype(int timerange)
{
121
  int tsteptype = TSTEP_INSTANT;
122
  static bool lprint = true;
123
124
125
126
127
128
129
130
131
132
133
134
135

  switch ( timerange )
    {
    case  0:  tsteptype = TSTEP_INSTANT;  break;
    case  1:  tsteptype = TSTEP_INSTANT2; break;
    case  2:  tsteptype = TSTEP_RANGE;    break;
    case  3:  tsteptype = TSTEP_AVG;      break;
    case  4:  tsteptype = TSTEP_ACCUM;    break;
    case  5:  tsteptype = TSTEP_DIFF;     break;
    case 10:  tsteptype = TSTEP_INSTANT3; break;
    default:
      if ( lprint )
	{
136
	  Message("Time range indicator %d unsupported, set to 0!", timerange);
137
	  lprint = false;
138
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
      break;
140
141
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
  return tsteptype;
143
144
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
145
static
146
void cgribexGetGrid(stream_t *streamptr, int *isec2, double *fsec2, int *isec4, grid_t *grid, int iret)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147
{
148
  bool compyinc = true;
149
  int gridtype = cgribexGetGridType(isec2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150

151
  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
152
    {
153
154
155
      int ilat, nlon = 0;
      for ( ilat = 0; ilat < ISEC2_NumLat; ++ilat )
        if ( ISEC2_RowLon(ilat) > nlon ) nlon = ISEC2_RowLon(ilat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
156
      gridtype = GRID_GAUSSIAN;
157
158
      ISEC2_NumLon = nlon;
      ISEC4_NumValues = nlon*ISEC2_NumLat;
159
      compyinc = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160
161
    }

162
  grid_init(grid);
163
  cdiGridTypeInit(grid, gridtype, 0);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
165
166
167
168
169
  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
	  Error("numberOfPoints (%d) and gridSize (%d) differ!", ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
171
	grid->size  = ISEC4_NumValues;
172
173
	grid->x.size = ISEC2_NumLon;
	grid->y.size = ISEC2_NumLat;
174
        if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
175
176
177
	grid->xinc  = 0;
	grid->yinc  = 0;
	grid->xdef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
179
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
180
	    if ( grid->x.size > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181
	      {
182
                bool recompinc = true;
183

184
185
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
187
                  {
188
                    if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->x.size-1))) <= 2 )
189
                      {
190
                        recompinc = false;
191
192
193
                        grid->xinc = ISEC2_LonIncr * 0.001;
                      }
                  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
194

195
		/* recompute xinc if necessary */
196
                if ( recompinc ) grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size-1);
197
198
199
200

		/* correct xinc if necessary */
		if ( ISEC2_FirstLon == 0 && ISEC2_LastLon > 354000 && ISEC2_LastLon < 360000 )
		  {
201
		    double xinc = 360. / grid->x.size;
202
203
204
205
206
207
208

		    if ( fabs(grid->xinc-xinc) > 0.0 )
		      {
			grid->xinc = xinc;
			if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
		      }
		  }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
	      }
210
211
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
212
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
	  }
214
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
216
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
217
	    if ( grid->y.size > 1 && compyinc )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
	      {
219
                bool recompinc = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
221
                  {
222
                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->y.size-1))) <= 2 )
223
                      {
224
                        recompinc = false;
225
226
227
                        grid->yinc = ISEC2_LatIncr * 0.001;
                      }
                  }
228

229
		/* recompute yinc if necessary */
230
                if ( recompinc ) grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
	      }
232
233
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
234
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235
236
237
238
239
	  }
	break;
      }
    case GRID_GAUSSIAN_REDUCED:
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
242
243
        grid->np      = ISEC2_NumPar;
	grid->size    = ISEC4_NumValues;
        grid->rowlon  = ISEC2_RowLonPtr;
	grid->nrowlon = ISEC2_NumLat;
244
	grid->y.size   = ISEC2_NumLat;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
245
246
247
	grid->xinc    = 0;
	grid->yinc    = 0;
	grid->xdef    = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
249
	/* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
	  {
250
	    if ( grid->x.size > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
	      {
252
253
                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
254
		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
255
		  grid->xinc = ISEC2_LonIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
		else
257
		  grid->xinc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
	      }
259
260
	    grid->xfirst = ISEC2_FirstLon * 0.001;
	    grid->xlast  = ISEC2_LastLon  * 0.001;
261
	    grid->xdef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
262
	  }
263
	grid->ydef  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
	/* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
	  {
266
	    if ( grid->y.size > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
268
	      {
		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
269
		  grid->yinc = ISEC2_LatIncr * 0.001;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270
		else
271
		  grid->yinc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272
	      }
273
274
	    grid->yfirst = ISEC2_FirstLat * 0.001;
	    grid->ylast  = ISEC2_LastLat  * 0.001;
275
	    grid->ydef   = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276
277
278
	  }
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
    case GRID_LCC:
280
281
      {
	if ( ISEC4_NumValues != ISEC2_NumLon*ISEC2_NumLat )
282
	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
283
		ISEC4_NumValues, ISEC2_NumLon*ISEC2_NumLat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284

285
	grid->size  = ISEC4_NumValues;
286
287
	grid->x.size = ISEC2_NumLon;
	grid->y.size = ISEC2_NumLat;
288

289
290
291
292
293
294
295
296
297
	grid->lcc.xinc      = ISEC2_Lambert_dx;
	grid->lcc.yinc      = ISEC2_Lambert_dy;
	grid->lcc.originLon = ISEC2_FirstLon * 0.001;
	grid->lcc.originLat = ISEC2_FirstLat * 0.001;
	grid->lcc.lonParY   = ISEC2_Lambert_Lov * 0.001;
	grid->lcc.lat1      = ISEC2_Lambert_LatS1 * 0.001;
	grid->lcc.lat2      = ISEC2_Lambert_LatS2 * 0.001;
	grid->lcc.projflag  = ISEC2_Lambert_ProjFlag;
	grid->lcc.scanflag  = ISEC2_ScanFlag;
298

299
	grid->xdef   = 0;
300
	grid->ydef   = 0;
301
302
303

	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
305
    case GRID_SPECTRAL:
      {
306
307
	grid->size  = ISEC4_NumValues;
	grid->trunc = ISEC2_PentaJ;
308
	if ( ISEC2_RepMode == 2 )
309
	  grid->lcomplex = 1;
310
	else
311
	  grid->lcomplex = 0;
312

Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
314
315
316
	break;
      }
    case GRID_GME:
      {
317
	grid->size  = ISEC4_NumValues;
318
319
320
321
	grid->gme.nd    = ISEC2_GME_ND;
	grid->gme.ni    = ISEC2_GME_NI;
	grid->gme.ni2   = ISEC2_GME_NI2;
	grid->gme.ni3   = ISEC2_GME_NI3;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322
323
324
325
	break;
      }
    case GRID_GENERIC:
      {
326
	grid->size  = ISEC4_NumValues;
327
328
	grid->x.size = 0;
	grid->y.size = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
330
331
332
	break;
      }
    default:
      {
333
	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
334
335
336
337
	break;
      }
    }

338
  grid->isRotated = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
339
  if ( cgribexGetIsRotated(isec2) )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
    {
341
      grid->isRotated = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343
      grid->ypole     = - ISEC2_LatSP*0.001;
      grid->xpole     =   ISEC2_LonSP*0.001 - 180;
344
      grid->angle     = - FSEC2_RotAngle;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
346
    }

347
348
349
350
  grid->type  = gridtype;
}

static
351
void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
352
		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
353
{
354
  int varID;
355
356
  int levelID = 0;

357
358
359
  int vlistID = streamptr->vlistID;
  int tsID    = streamptr->curTsID;
  int recID   = recordNewEntry(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
  record_t *record = &streamptr->tsteps[tsID].records[recID];
361

362
363
  int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
  int numavg    = ISEC1_AvgNum;
364

365
366
  int level1  = ISEC1_Level1;
  int level2  = ISEC1_Level2;
367
368
369

  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */

370
371
372
373
374
375
  record->size      = (size_t)recsize;
  record->position  = position;
  record->param     = param;
  record->ilevel    = level1;
  record->ilevel2   = level2;
  record->ltype     = ISEC1_LevelType;
Thomas Jahns's avatar
Thomas Jahns committed
376
  record->tsteptype = (short)tsteptype;
377

Uwe Schulzweida's avatar
Uwe Schulzweida committed
378
379
  grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
  cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
380

Uwe Schulzweida's avatar
Uwe Schulzweida committed
381
  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
382
  int gridID = gridAdded.Id;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
383
384
385
386
387
388
389
390
391
392
393
394
  if ( gridAdded.isNew )
    {
      if ( gridptr->nrowlon )
        {
          size_t nrowlon = (size_t) gridptr->nrowlon;
          int *rowlon = gridptr->rowlon;
          gridptr->rowlon = (int*) Malloc(nrowlon * sizeof(int));
          memcpy(gridptr->rowlon, rowlon, nrowlon * sizeof(int));
        }
    }
  else
    Free(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395

396
  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397

398
  if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
    {
400
      size_t vctsize = (size_t)ISEC2_NumVCP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
402
403
404
405
      double *vctptr = &fsec2[10];

      varDefVCT(vctsize, vctptr);
    }

406
  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
407

408
409
  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
  if ( datatype <  0 ) datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
410

411
  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
412
413
	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
               NULL, NULL, NULL, NULL, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414

Thomas Jahns's avatar
Thomas Jahns committed
415
416
  record->varID   = (short)varID;
  record->levelID = (short)levelID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
417

418
  varDefCompType(varID, comptype);
419

420
421
422
423
424
425
426
  if ( ISEC1_LocalFLag )
    {
      if      ( ISEC1_CenterID == 78  && isec1[36] == 253 ) // DWD local extension
        varDefEnsembleInfo(varID, isec1[54], isec1[53], isec1[52]);
      else if ( ISEC1_CenterID == 252 && isec1[36] ==   1 ) // MPIM local extension
        varDefEnsembleInfo(varID, isec1[38], isec1[39], isec1[37]);
    }
427

428
429
  if ( lmv ) varDefMissval(varID, FSEC3_MissVal);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
  if ( varInqInst(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
431
432
433
434
435
    {
      int center, subcenter, instID;
      center    = ISEC1_CenterID;
      subcenter = ISEC1_SubCenterID;
      instID    = institutInq(center, subcenter, NULL, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
436
      if ( instID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
437
438
439
440
	instID = institutDef(center, subcenter, NULL, NULL);
      varDefInst(varID, instID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
441
  if ( varInqModel(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
442
443
444
    {
      int modelID;
      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
445
      if ( modelID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446
447
448
449
	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
      varDefModel(varID, modelID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
450
  if ( varInqTable(varID) == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
452
    {
      int tableID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453

Uwe Schulzweida's avatar
Uwe Schulzweida committed
454
      tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455

Uwe Schulzweida's avatar
Uwe Schulzweida committed
456
      if ( tableID == CDI_UNDEFID )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
458
459
460
	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
      varDefTable(varID, tableID);
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
462
  streamptr->tsteps[tsID].nallrecs++;
  streamptr->nrecs++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
463
464
}

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
static
void MCH_get_undef(int *isec1, double *undef_pds, double *undef_eps)
{
  /* 2010-01-13: Oliver Fuhrer */
  if ( ISEC1_CenterID == 215 ) {
    if (isec1[34] != 0 && isec1[34] != 255) {
      if (isec1[34] & 2) {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,-isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,-isec1[35]);
        }
        *undef_eps = pow(10.0,-isec1[35]-1);
      } else {
        if (isec1[34] & 1) {
          *undef_pds = -0.99*pow(10.0,+isec1[35]);
        } else {
          *undef_pds = +0.99*pow(10.0,+isec1[35]);
        }
        *undef_eps = pow(10.0,isec1[35]-1);
      }
    }
  }
}

static
void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
492
			 int *isec3, double *fsec3, int *isec4, double *fsec4,
493
			 int *gribbuffer, int recsize, int *lmv, int *iret)
494
{
495
  int ipunp = 0, iword = 0;
496

497
498
  memset(isec1, 0, 256*sizeof(int));

499
  gribExDP(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
500
	   ipunp, (int *) gribbuffer, recsize, &iword, "J", iret);
501
502
503
504
505
506
507
508
509
510
511
512

  *lmv = 0;

  if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
    {
      double undef_pds, undef_eps;

      MCH_get_undef(isec1, &undef_pds, &undef_eps);
      FSEC3_MissVal = undef_pds;
      *lmv = 1;
    }
}
513
514

static
515
compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
516
517
{
  compvar_t compVar;
518
  int tsteptype = cgribexGetTsteptype(trange);
519

520
521
522
523
524
  compVar.param     = param;
  compVar.level1    = level1;
  compVar.level2    = level2;
  compVar.ltype     = leveltype;
  compVar.tsteptype = tsteptype;
525

Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
  return compVar;
527
528
}

Thomas Jahns's avatar
Thomas Jahns committed
529
530
static inline int
cgribexVarCompare(compvar_t compVar, record_t record, int flag)
531
{
Thomas Jahns's avatar
Thomas Jahns committed
532
533
534
535
  int tstepDiff = (!((flag == 0) & (((compVar.tsteptype == TSTEP_INSTANT)
                                     & (record.tsteptype == TSTEP_INSTANT3))
                                    |((compVar.tsteptype == TSTEP_INSTANT3)
                                      & (record.tsteptype == TSTEP_INSTANT)))))
Thomas Jahns's avatar
Thomas Jahns committed
536
537
538
539
540
541
    & (compVar.tsteptype != record.tsteptype);
  int rstatus = (compVar.param != record.param)
    |           (compVar.level1 != record.ilevel)
    |           (compVar.level2 != record.ilevel2)
    |           (compVar.ltype != record.ltype)
    |           tstepDiff;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
  return rstatus;
543
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
544
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545

546
547
548
#define gribWarning(text, nrecs, timestep, paramstr, level1, level2) \
            Warning("Record %2d (id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, paramstr, level1, level2, timestep, text)

549
#if  defined  (HAVE_LIBCGRIBEX)
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582

static inline void
cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
{
  if ( streamptr->ntsteps == -1 )
    {
      int tsID = tstepsNewEntry(streamptr);
      if ( tsID != streamptr->rtsteps )
	Error("Internal error. tsID = %d", tsID);

      streamptr->tsteps[tsID-1].next   = TRUE;
      streamptr->tsteps[tsID].position = recpos;
    }
}

static inline void
cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
{
  int vlistID = streamptr->vlistID;
  if ( streamptr->ntsteps == 1 )
    {
      if ( taxis->vdate == 0 && taxis->vtime == 0 )
	{
	  streamptr->ntsteps = 0;
	  for (int varID = 0; varID < streamptr->nvars; varID++ )
	    {
	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
	    }
	}
    }
}


583
int cgribexScanTimestep1(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
585
{
  double fsec2[512], fsec3[2], *fsec4 = NULL;
586
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587
  off_t recpos = 0;
588
  void *gribbuffer = NULL;
589
  size_t buffersize = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590
  int rstatus;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
591
592
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
593
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
  size_t readsize;
595
  unsigned nrecords, recID;
596
  int nrecs_scanned = 0;
597
  int datatype;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
  long recsize = 0;
599
600
  bool warn_time = true;
  bool warn_numavg = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601
  int taxisID = -1;
602
603
  int rdate = 0, rtime = 0, tunit = 0;
  bool fcast = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
604
  int vlistID;
605
  int comptype;
606
  long unzipsize;
607
  char paramstr[32];
608
  int nskip = cdiSkipRecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
609
610

  streamptr->curTsID = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611

612
613
614
615
616
  int *isec0 = streamptr->record->sec0;
  int *isec1 = streamptr->record->sec1;
  int *isec2 = streamptr->record->sec2;
  int *isec3 = streamptr->record->sec3;
  int *isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617

618
619
  int tsID  = tstepsNewEntry(streamptr);
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
620
621

  if ( tsID != 0 )
622
    Error("Internal problem! tstepsNewEntry returns %d", tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623

624
  int fileID = streamptr->fileID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625

626
627
628
  while ( nskip-- > 0 )
    {
      recsize = gribGetSize(fileID);
629
      if ( recsize == 0 )
630
	Error("Skipping of %d records failed!", cdiSkipRecords);
631

632
      recpos  = fileGetPos(fileID);
633
      fileSetPos(fileID, (off_t)recsize, SEEK_CUR);
634
635
    }

636
  unsigned nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637
638
639
640
641
642
643
  while ( TRUE )
    {
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);

      if ( recsize == 0 )
	{
644
	  if ( nrecs == 0 )
645
	    Error("No GRIB records found!");
646

Uwe Schulzweida's avatar
Uwe Schulzweida committed
647
	  streamptr->ntsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
649
	  break;
	}
650
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
	{
652
	  buffersize = (size_t)recsize;
653
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
654
655
	}

656
      readsize = (size_t)recsize;
657
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
658
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
659

660
      comptype = COMPRESS_NONE;
661
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
662
	{
663
	  comptype = COMPRESS_SZIP;
664
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
665
	  if ( buffersize < (size_t)unzipsize )
666
	    {
667
	      buffersize = (size_t)unzipsize;
668
	      gribbuffer = Realloc(gribbuffer, buffersize);
669
670
671
	    }
	}

672
      nrecs_scanned++;
673
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
674
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675

Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
677
678
      cdiParamToString(param, paramstr, sizeof(paramstr));

679
680
      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
681
682
683
      level1   = ISEC1_Level1;
      level2   = ISEC1_Level2;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
684
685
      gribDateTime(isec1, &vdate, &vtime);

686
      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
687
	datatype = ISEC4_NumBits;
688
      else
689
        datatype = DATATYPE_PACK;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
691
692
693
694
695
696

      if ( nrecs == 0 )
	{
	  datetime0.date = vdate;
	  datetime0.time = vtime;
	  rdate = gribRefDate(isec1);
	  rtime = gribRefTime(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
697
	  tunit = cgribexGetTimeUnit(isec1);
698
	  fcast = cgribexTimeIsFC(isec1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
699
700
701
702
703
	}
      else
	{
	  datetime.date  = vdate;
	  datetime.time  = vtime;
704
	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
706
	  for ( recID = 0; recID < nrecs; recID++ )
	    {
707
	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
709
710
711
712
713

	  if ( cdiInventoryMode == 1 )
	    {
	      if ( recID < nrecs ) break;
	      if ( warn_time )
714
		if ( datetimeCmp(datetime, datetime0) != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
		  {
716
                    gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, paramstr, level1, level2);
717
		    warn_time = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
718
719
720
721
		  }
	    }
	  else
	    {
722
	      if ( datetimeCmp(datetime, datetime0) != 0 ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
723
724
725

	      if ( recID < nrecs )
		{
726
		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, paramstr, level1, level2);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727
728
729
		  continue;
		}
	    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
731
732
733
734
735
	}

      if ( ISEC1_AvgNum )
	{
	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
	    {
736
	      Warning("Changing numavg from %d to %d not supported!", taxis->numavg, ISEC1_AvgNum);
737
	      warn_numavg = false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
739
740
741
742
743
744
745
746
747
	    }
	  else
	    {
	      taxis->numavg = ISEC1_AvgNum;
	    }
	}

      nrecs++;

      if ( CDI_Debug )
748
	Message("Read record %2d (id=%s lev1=%d lev2=%d) %8d %6d", nrecs_scanned, paramstr, level1, level2, vdate, vtime);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749

750
      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
751
		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
752
753
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
  streamptr->rtsteps = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755

Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
  if ( nrecs == 0 ) return CDI_EUFSTRUCT;
757

758
  cdi_generate_vars(streamptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
759
760
761

  if ( fcast )
    {
762
      taxisID = taxisCreate(TAXIS_RELATIVE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764
765
766
767
768
769
      taxis->type  = TAXIS_RELATIVE;
      taxis->rdate = rdate;
      taxis->rtime = rtime;
      taxis->unit  = tunit;
    }
  else
    {
770
      taxisID = taxisCreate(TAXIS_ABSOLUTE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
771
      taxis->type  = TAXIS_ABSOLUTE;
772
      taxis->unit  = tunit;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
773
774
    }

775
776
  taxis->vdate = (int)datetime0.date;
  taxis->vtime = (int)datetime0.time;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777

Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
  vlistID = streamptr->vlistID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
780
  vlistDefTaxis(vlistID, taxisID);

781
782
  nrecords = (unsigned)streamptr->tsteps[0].nallrecs;
  if ( nrecords < (unsigned)streamptr->tsteps[0].recordSize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
    {
784
      streamptr->tsteps[0].recordSize = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
      streamptr->tsteps[0].records =
786
      (record_t *) Realloc(streamptr->tsteps[0].records, nrecords*sizeof(record_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
788
    }

789
  streamptr->tsteps[0].recIDs = (int *) Malloc(nrecords*sizeof(int));
790
  streamptr->tsteps[0].nrecs = (int)nrecords;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
  for ( recID = 0; recID < nrecords; recID++ )
792
    streamptr->tsteps[0].recIDs[recID] = (int)recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793

Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
  streamptr->record->buffer     = gribbuffer;
795
  streamptr->record->buffersize = (size_t)buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
796

797
798
  cgribexScanTsFixNtsteps(streamptr, recpos);
  cgribexScanTsConstAdjust(streamptr, taxis);
799

Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
  return 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
803

804
int cgribexScanTimestep2(stream_t * streamptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
806
  int rstatus = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
  double fsec2[512], fsec3[2], *fsec4 = NULL;
808
  int lmv = 0, iret = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
  off_t recpos = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810
811
  int param = 0;
  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
812
  DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
Uwe Schulzweida's avatar
Uwe Schulzweida committed
813
814
  int varID, gridID;
  size_t readsize;
815
  int nrecs, recID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816
  long recsize = 0;
817
  bool warn_numavg = true;
818
  int tsteptype;
819
  long unzipsize;
820
  char paramstr[32];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
821

Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
823
  streamptr->curTsID = 1;

824
825
826
827
828
  int *isec0 = streamptr->record->sec0;
  int *isec1 = streamptr->record->sec1;
  int *isec2 = streamptr->record->sec2;
  int *isec3 = streamptr->record->sec3;
  int *isec4 = streamptr->record->sec4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
829

830
831
832
  int fileID  = streamptr->fileID;
  int vlistID = streamptr->vlistID;
  int taxisID = vlistInqTaxis(vlistID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833

834
835
  void *gribbuffer = streamptr->record->buffer;
  size_t buffersize = streamptr->record->buffersize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836

837
  int tsID = streamptr->rtsteps;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
  if ( tsID != 1 )
Thomas Jahns's avatar
Thomas Jahns committed
839
    Error("Internal problem! unexpected timestep %d", tsID+1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840

841
  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842

Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
  fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844

845
  cdi_create_records(streamptr, tsID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846

847
  int nrecords = streamptr->tsteps[tsID].nallrecs;
848
  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
  streamptr->tsteps[1].nrecs = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850
  for ( recID = 0; recID < nrecords; recID++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
    streamptr->tsteps[1].recIDs[recID] = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
852

Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
854
  for ( recID = 0; recID < nrecords; recID++ )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
      varID = streamptr->tsteps[0].records[recID].varID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
857
      streamptr->tsteps[tsID].records[recID].position =	streamptr->tsteps[0].records[recID].position;
      streamptr->tsteps[tsID].records[recID].size     =	streamptr->tsteps[0].records[recID].size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
859
    }

860
861
  int nrecs_scanned = nrecords;
  int rindex = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
  while ( TRUE )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
865
      if ( rindex > nrecords ) break;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
867
868
869
      recsize = gribGetSize(fileID);
      recpos  = fileGetPos(fileID);
      if ( recsize == 0 )
	{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
870
	  streamptr->ntsteps = 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
872
	  break;
	}
873
      if ( (size_t)recsize > buffersize )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
874
	{
875
	  buffersize = (size_t)recsize;
876
	  gribbuffer = Realloc(gribbuffer, buffersize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877
878
	}

879
      readsize = (size_t)recsize;
880
      rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
      if ( rstatus ) break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882

883
      if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
884
885
	{
	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
886
	  if ( buffersize < (size_t)unzipsize )
887
	    {
888
	      buffersize = (size_t)unzipsize;
889
	      gribbuffer = Realloc(gribbuffer, buffersize);
890
891
892
	    }
	}

893
      cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
894
			  (int *) gribbuffer, (int)recsize, &lmv, &iret);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
895

896
897
      nrecs_scanned++;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
898
      param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
899
900
      cdiParamToString(param, paramstr, sizeof(paramstr));

901
902
      if ( ISEC1_LevelType == 100 )