Line data Source code
1 : #include <stdio.h>
2 : #include <stdlib.h>
3 : #include <assert.h>
4 : #include "grib2.h"
5 :
6 472 : g2int g2_getfld(unsigned char *cgrib,g2int cgrib_length, g2int ifldnum,g2int unpack,g2int expand,
7 : gribfield **gfld)
8 : //$$$ SUBPROGRAM DOCUMENTATION BLOCK
9 : // . . . .
10 : // SUBPROGRAM: g2_getfld
11 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-28
12 : //
13 : // ABSTRACT: This subroutine returns all the metadata, template values,
14 : // Bit-map ( if applicable ), and the unpacked data for a given data
15 : // field. All of the information returned is stored in a gribfield
16 : // structure, which is defined in file grib2.h.
17 : // Users of this routine will need to include "grib2.h" in their source
18 : // code that calls this routine. Each component of the gribfield
19 : // struct is also described in the OUTPUT ARGUMENTS section below.
20 : //
21 : // Since there can be multiple data fields packed into a GRIB2
22 : // message, the calling routine indicates which field is being requested
23 : // with the ifldnum argument.
24 : //
25 : // PROGRAM HISTORY LOG:
26 : // 2002-10-28 Gilbert
27 : //
28 : // USAGE: #include "grib2.h"
29 : // int g2_getfld(unsigned char *cgrib,g2int ifldnum,g2int unpack,
30 : // g2int expand,gribfield **gfld)
31 : // INPUT ARGUMENTS:
32 : // cgrib - Character pointer to the GRIB2 message
33 : // ifldnum - Specifies which field in the GRIB2 message to return.
34 : // unpack - Boolean value indicating whether to unpack bitmap/data field
35 : // 1 = unpack bitmap (if present) and data values
36 : // 0 = do not unpack bitmap and data values
37 : // expand - Boolean value indicating whether the data points should be
38 : // expanded to the correspond grid, if a bit-map is present.
39 : // 1 = if possible, expand data field to grid, inserting zero
40 : // values at gridpoints that are bitmapped out.
41 : // (SEE REMARKS2)
42 : // 0 = do not expand data field, leaving it an array of
43 : // consecutive data points for each "1" in the bitmap.
44 : // This argument is ignored if unpack == 0 OR if the
45 : // returned field does not contain a bit-map.
46 : //
47 : // OUTPUT ARGUMENT:
48 : // gribfield gfld; - pointer to structure gribfield containing
49 : // all decoded data for the data field.
50 : //
51 : // gfld->version = GRIB edition number ( currently 2 )
52 : // gfld->discipline = Message Discipline ( see Code Table 0.0 )
53 : // gfld->idsect = Contains the entries in the Identification
54 : // Section ( Section 1 )
55 : // This element is a pointer to an array
56 : // that holds the data.
57 : // gfld->idsect[0] = Identification of originating Centre
58 : // ( see Common Code Table C-1 )
59 : // 7 - US National Weather Service
60 : // gfld->idsect[1] = Identification of originating Sub-centre
61 : // gfld->idsect[2] = GRIB Master Tables Version Number
62 : // ( see Code Table 1.0 )
63 : // 0 - Experimental
64 : // 1 - Initial operational version number
65 : // gfld->idsect[3] = GRIB Local Tables Version Number
66 : // ( see Code Table 1.1 )
67 : // 0 - Local tables not used
68 : // 1-254 - Number of local tables version used
69 : // gfld->idsect[4] = Significance of Reference Time (Code Table 1.2)
70 : // 0 - Analysis
71 : // 1 - Start of forecast
72 : // 2 - Verifying time of forecast
73 : // 3 - Observation time
74 : // gfld->idsect[5] = Year ( 4 digits )
75 : // gfld->idsect[6] = Month
76 : // gfld->idsect[7) = Day
77 : // gfld->idsect[8] = Hour
78 : // gfld->idsect[9] = Minute
79 : // gfld->idsect[10] = Second
80 : // gfld->idsect[11] = Production status of processed data
81 : // ( see Code Table 1.3 )
82 : // 0 - Operational products
83 : // 1 - Operational test products
84 : // 2 - Research products
85 : // 3 - Re-analysis products
86 : // gfld->idsect[12] = Type of processed data ( see Code Table 1.4 )
87 : // 0 - Analysis products
88 : // 1 - Forecast products
89 : // 2 - Analysis and forecast products
90 : // 3 - Control forecast products
91 : // 4 - Perturbed forecast products
92 : // 5 - Control and perturbed forecast products
93 : // 6 - Processed satellite observations
94 : // 7 - Processed radar observations
95 : // gfld->idsectlen = Number of elements in gfld->idsect[].
96 : // gfld->local = Pointer to character array containing contents
97 : // of Local Section 2, if included
98 : // gfld->locallen = length of array gfld->local[]
99 : // gfld->ifldnum = field number within GRIB message
100 : // gfld->griddef = Source of grid definition (see Code Table 3.0)
101 : // 0 - Specified in Code table 3.1
102 : // 1 - Predetermined grid Defined by originating centre
103 : // gfld->ngrdpts = Number of grid points in the defined grid.
104 : // gfld->numoct_opt = Number of octets needed for each
105 : // additional grid points definition.
106 : // Used to define number of
107 : // points in each row ( or column ) for
108 : // non-regular grids.
109 : // = 0, if using regular grid.
110 : // gfld->interp_opt = Interpretation of list for optional points
111 : // definition. (Code Table 3.11)
112 : // gfld->igdtnum = Grid Definition Template Number (Code Table 3.1)
113 : // gfld->igdtmpl = Contains the data values for the specified Grid
114 : // Definition Template ( NN=gfld->igdtnum ). Each
115 : // element of this integer array contains an entry (in
116 : // the order specified) of Grid Definition Template 3.NN
117 : // This element is a pointer to an array
118 : // that holds the data.
119 : // gfld->igdtlen = Number of elements in gfld->igdtmpl[]. i.e. number of
120 : // entries in Grid Definition Template 3.NN
121 : // ( NN=gfld->igdtnum ).
122 : // gfld->list_opt = (Used if gfld->numoct_opt .ne. 0) This array
123 : // contains the number of grid points contained in
124 : // each row ( or column ). (part of Section 3)
125 : // This element is a pointer to an array
126 : // that holds the data. This pointer is nullified
127 : // if gfld->numoct_opt=0.
128 : // gfld->num_opt = (Used if gfld->numoct_opt .ne. 0)
129 : // The number of entries
130 : // in array ideflist. i.e. number of rows ( or columns )
131 : // for which optional grid points are defined. This value
132 : // is set to zero, if gfld->numoct_opt=0.
133 : // gfdl->ipdtnum = Product Definition Template Number(see Code Table 4.0)
134 : // gfld->ipdtmpl = Contains the data values for the specified Product
135 : // Definition Template ( N=gfdl->ipdtnum ). Each element
136 : // of this integer array contains an entry (in the
137 : // order specified) of Product Definition Template 4.N.
138 : // This element is a pointer to an array
139 : // that holds the data.
140 : // gfld->ipdtlen = Number of elements in gfld->ipdtmpl[]. i.e. number of
141 : // entries in Product Definition Template 4.N
142 : // ( N=gfdl->ipdtnum ).
143 : // gfld->coord_list = Real array containing floating point values
144 : // intended to document the vertical discretisation
145 : // associated to model data on hybrid coordinate
146 : // vertical levels. (part of Section 4)
147 : // This element is a pointer to an array
148 : // that holds the data.
149 : // gfld->num_coord = number of values in array gfld->coord_list[].
150 : // gfld->ndpts = Number of data points unpacked and returned.
151 : // gfld->idrtnum = Data Representation Template Number
152 : // ( see Code Table 5.0)
153 : // gfld->idrtmpl = Contains the data values for the specified Data
154 : // Representation Template ( N=gfld->idrtnum ). Each
155 : // element of this integer array contains an entry
156 : // (in the order specified) of Product Definition
157 : // Template 5.N.
158 : // This element is a pointer to an array
159 : // that holds the data.
160 : // gfld->idrtlen = Number of elements in gfld->idrtmpl[]. i.e. number
161 : // of entries in Data Representation Template 5.N
162 : // ( N=gfld->idrtnum ).
163 : // gfld->unpacked = logical value indicating whether the bitmap and
164 : // data values were unpacked. If false,
165 : // gfld->bmap and gfld->fld pointers are nullified.
166 : // gfld->expanded = Logical value indicating whether the data field
167 : // was expanded to the grid in the case where a
168 : // bit-map is present. If true, the data points in
169 : // gfld->fld match the grid points and zeros were
170 : // inserted at grid points where data was bit-mapped
171 : // out. If false, the data values in gfld->fld were
172 : // not expanded to the grid and are just a consecutive
173 : // array of data points corresponding to each value of
174 : // "1" in gfld->bmap.
175 : // gfld->ibmap = Bitmap indicator ( see Code Table 6.0 )
176 : // 0 = bitmap applies and is included in Section 6.
177 : // 1-253 = Predefined bitmap applies
178 : // 254 = Previously defined bitmap applies to this field
179 : // 255 = Bit map does not apply to this product.
180 : // gfld->bmap = integer array containing decoded bitmap,
181 : // if gfld->ibmap=0 or gfld->ibap=254. Otherwise nullified
182 : // This element is a pointer to an array
183 : // that holds the data.
184 : // gfld->fld = Array of gfld->ndpts unpacked data points.
185 : // This element is a pointer to an array
186 : // that holds the data.
187 : //
188 : //
189 : // RETURN VALUES:
190 : // ierr - Error return code.
191 : // 0 = no error
192 : // 1 = Beginning characters "GRIB" not found.
193 : // 2 = GRIB message is not Edition 2.
194 : // 3 = The data field request number was not positive.
195 : // 4 = End string "7777" found, but not where expected.
196 : // 6 = GRIB message did not contain the requested number of
197 : // data fields.
198 : // 7 = End string "7777" not found at end of message.
199 : // 8 = Unrecognized Section encountered.
200 : // 9 = Data Representation Template 5.NN not yet implemented.
201 : // 15 = Error unpacking Section 1.
202 : // 16 = Error unpacking Section 2.
203 : // 10 = Error unpacking Section 3.
204 : // 11 = Error unpacking Section 4.
205 : // 12 = Error unpacking Section 5.
206 : // 13 = Error unpacking Section 6.
207 : // 14 = Error unpacking Section 7.
208 : // 17 = Previous bitmap specified, yet none exists.
209 : //
210 : // REMARKS: Note that struct gribfield is allocated by this routine and it
211 : // also contains pointers to many arrays of data that were allocated
212 : // during decoding. Users are encouraged to free up this memory,
213 : // when it is no longer needed, by an explicit call to routine g2_free.
214 : // EXAMPLE:
215 : // #include "grib2.h"
216 : // gribfield *gfld;
217 : // ret=g2_getfld(cgrib,1,1,1,&gfld);
218 : // ...
219 : // g2_free(gfld);
220 : //
221 : // Routine g2_info can be used to first determine
222 : // how many data fields exist in a given GRIB message.
223 : //
224 : // REMARKS2: It may not always be possible to expand a bit-mapped data field.
225 : // If a pre-defined bit-map is used and not included in the GRIB2
226 : // message itself, this routine would not have the necessary
227 : // information to expand the data. In this case, gfld->expanded would
228 : // would be set to 0 (false), regardless of the value of input
229 : // argument expand.
230 : //
231 : // ATTRIBUTES:
232 : // LANGUAGE: C
233 : // MACHINE:
234 : //
235 : //$$$
236 : {
237 :
238 : g2int have3,have4,have5,have6,have7,ierr,jerr;
239 : g2int numfld,j,n,istart,iofst,ipos;
240 : g2int disc,ver,lensec0,lengrib,lensec,isecnum;
241 : g2int *igds;
242 : g2int *bmpsave;
243 : g2float *newfld;
244 : gribfield *lgfld;
245 472 : int iofst_last_sect6 = -1;
246 :
247 472 : have3=0;
248 472 : have4=0;
249 472 : have5=0;
250 472 : have6=0;
251 472 : have7=0;
252 472 : ierr=0;
253 472 : numfld=0;
254 :
255 472 : lgfld=(gribfield *)malloc(sizeof(gribfield));
256 472 : *gfld=lgfld;
257 :
258 472 : lgfld->locallen=0;
259 472 : lgfld->idsect=0;
260 472 : lgfld->local=0;
261 472 : lgfld->list_opt=0;
262 472 : lgfld->igdtmpl=0;
263 472 : lgfld->ipdtmpl=0;
264 472 : lgfld->idrtmpl=0;
265 472 : lgfld->coord_list=0;
266 472 : lgfld->bmap=0;
267 472 : lgfld->fld=0;
268 472 : lgfld->ngrdpts=0;
269 : //
270 : // Check for valid request number
271 : //
272 472 : if (ifldnum <= 0) {
273 0 : printf("g2_getfld: Request for field number must be positive.\n");
274 0 : ierr=3;
275 0 : return(ierr);
276 : }
277 : //
278 : // Check for beginning of GRIB message in the first 100 bytes
279 : //
280 472 : istart=-1;
281 472 : for (j=0;j<100;j++) {
282 472 : if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' &&
283 472 : cgrib[j+3]=='B') {
284 472 : istart=j;
285 472 : break;
286 : }
287 : }
288 472 : if (istart == -1) {
289 0 : printf("g2_getfld: Beginning characters GRIB not found.\n");
290 0 : ierr=1;
291 0 : return(ierr);
292 : }
293 : //
294 : // Unpack Section 0 - Indicator Section
295 : //
296 472 : iofst=8*(istart+6);
297 472 : gbit(cgrib,&disc,iofst,8); // Discipline
298 472 : iofst=iofst+8;
299 472 : gbit(cgrib,&ver,iofst,8); // GRIB edition number
300 472 : iofst=iofst+8;
301 472 : iofst=iofst+32;
302 472 : gbit(cgrib,&lengrib,iofst,32); // Length of GRIB message
303 472 : iofst=iofst+32;
304 472 : lensec0=16;
305 472 : ipos=istart+lensec0;
306 : //
307 : // Currently handles only GRIB Edition 2.
308 : //
309 472 : if (ver != 2) {
310 0 : printf("g2_getfld: can only decode GRIB edition 2.\n");
311 0 : ierr=2;
312 0 : return(ierr);
313 : }
314 : //
315 : // Loop through the remaining sections keeping track of the
316 : // length of each. Also keep the latest Grid Definition Section info.
317 : // Unpack the requested field number.
318 : //
319 : for (;;) {
320 : // Check to see if we are at end of GRIB message
321 2971 : if (cgrib[ipos]=='7' && cgrib[ipos+1]=='7' && cgrib[ipos+2]=='7' &&
322 0 : cgrib[ipos+3]=='7') {
323 0 : ipos=ipos+4;
324 : // If end of GRIB message not where expected, issue error
325 0 : if (ipos != (istart+lengrib)) {
326 0 : printf("g2_getfld: '7777' found, but not where expected.\n");
327 0 : ierr=4;
328 0 : return(ierr);
329 : }
330 0 : break;
331 : }
332 : // Get length of Section and Section number
333 : //iofst=(ipos-1)*8;
334 2971 : iofst=ipos*8;
335 2971 : gbit(cgrib,&lensec,iofst,32); // Get Length of Section
336 2971 : iofst=iofst+32;
337 2971 : gbit(cgrib,&isecnum,iofst,8); // Get Section number
338 2971 : iofst=iofst+8;
339 : //printf(" lensec= %ld secnum= %ld \n",lensec,isecnum);
340 : //
341 : // Check to see if section number is valid
342 : //
343 2971 : if ( isecnum<1 || isecnum>7 ) {
344 0 : printf("g2_getfld: Unrecognized Section Encountered=%d\n",isecnum);
345 0 : ierr=8;
346 0 : return(ierr);
347 : }
348 : //
349 : // If found Section 1, decode elements in Identification Section
350 : //
351 2971 : if (isecnum == 1) {
352 472 : iofst=iofst-40; // reset offset to beginning of section
353 472 : jerr=g2_unpack1(cgrib,&iofst,&lgfld->idsect,&lgfld->idsectlen);
354 472 : if (jerr !=0 ) {
355 0 : ierr=15;
356 0 : return(ierr);
357 : }
358 : }
359 : //
360 : // If found Section 2, Grab local section
361 : // Save in case this is the latest one before the requested field.
362 : //
363 2971 : if (isecnum == 2) {
364 436 : iofst=iofst-40; // reset offset to beginning of section
365 436 : if (lgfld->local!=0) free(lgfld->local);
366 436 : jerr=g2_unpack2(cgrib,&iofst,&lgfld->locallen,&lgfld->local);
367 436 : if (jerr != 0) {
368 0 : ierr=16;
369 0 : return(ierr);
370 : }
371 : }
372 : //
373 : // If found Section 3, unpack the GDS info using the
374 : // appropriate template. Save in case this is the latest
375 : // grid before the requested field.
376 : //
377 2971 : if (isecnum == 3) {
378 472 : iofst=iofst-40; // reset offset to beginning of section
379 472 : if (lgfld->igdtmpl!=0) free(lgfld->igdtmpl);
380 472 : if (lgfld->list_opt!=0) free(lgfld->list_opt);
381 472 : jerr=g2_unpack3(cgrib,cgrib_length,&iofst,&igds,&lgfld->igdtmpl,
382 : &lgfld->igdtlen,&lgfld->list_opt,&lgfld->num_opt);
383 472 : if (jerr == 0) {
384 472 : have3=1;
385 472 : lgfld->griddef=igds[0];
386 472 : lgfld->ngrdpts=igds[1];
387 472 : lgfld->numoct_opt=igds[2];
388 472 : lgfld->interp_opt=igds[3];
389 472 : lgfld->igdtnum=igds[4];
390 472 : free(igds);
391 : }
392 : else {
393 0 : ierr=10;
394 0 : free( igds );
395 0 : return(ierr);
396 : }
397 : }
398 : //
399 : // If found Section 4, check to see if this field is the
400 : // one requested.
401 : //
402 2971 : if (isecnum == 4) {
403 475 : numfld=numfld+1;
404 475 : if (numfld == ifldnum) {
405 472 : lgfld->discipline=disc;
406 472 : lgfld->version=ver;
407 472 : lgfld->ifldnum=ifldnum;
408 472 : lgfld->unpacked=unpack;
409 472 : lgfld->expanded=0;
410 472 : iofst=iofst-40; // reset offset to beginning of section
411 472 : jerr=g2_unpack4(cgrib,cgrib_length,&iofst,&lgfld->ipdtnum,
412 : &lgfld->ipdtmpl,&lgfld->ipdtlen,&lgfld->coord_list,
413 : &lgfld->num_coord);
414 472 : if (jerr == 0 || jerr == 5 )
415 472 : have4=1;
416 : else {
417 0 : ierr=11;
418 0 : return(ierr);
419 : }
420 : }
421 : }
422 : //
423 : // If found Section 5, check to see if this field is the
424 : // one requested.
425 : //
426 2971 : if (isecnum == 5 && numfld == ifldnum) {
427 472 : iofst=iofst-40; // reset offset to beginning of section
428 472 : jerr=g2_unpack5(cgrib,cgrib_length,&iofst,&lgfld->ndpts,&lgfld->idrtnum,
429 : &lgfld->idrtmpl,&lgfld->idrtlen);
430 472 : if (jerr == 0)
431 472 : have5=1;
432 : else {
433 0 : ierr=12;
434 0 : return(ierr);
435 : }
436 : }
437 : //
438 : // If found Section 6, Unpack bitmap.
439 : // Save in case this is the latest
440 : // bitmap before the requested field.
441 : //
442 2971 : if (isecnum == 6) {
443 475 : if (numfld==ifldnum && unpack) { // unpack bitmap
444 163 : iofst=iofst-40; // reset offset to beginning of section
445 163 : bmpsave=lgfld->bmap; // save pointer to previous bitmap
446 163 : jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap,
447 : &lgfld->bmap);
448 163 : if (jerr == 0) {
449 163 : have6=1;
450 163 : if (lgfld->ibmap == 254) // use previously specified bitmap
451 1 : if( bmpsave!=0 )
452 0 : lgfld->bmap=bmpsave;
453 : else {
454 :
455 1 : if( ifldnum > 1 && iofst_last_sect6 > 0 )
456 1 : {
457 : /* Unpack the last valid section 6 we read before */
458 1 : int iofst_backup = iofst;
459 1 : iofst = iofst_last_sect6 - 40;
460 1 : jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap,
461 : &lgfld->bmap);
462 1 : lgfld->ibmap = 254;
463 1 : iofst = iofst_backup;
464 1 : if( jerr != 0 ) {
465 0 : ierr=13;
466 0 : return(ierr);
467 : }
468 : }
469 : else
470 : {
471 0 : printf("g2_getfld: Prev bit-map specified, but none exist.\n");
472 0 : ierr=17;
473 0 : return(ierr);
474 : }
475 : }
476 : else // get rid of it
477 162 : if( bmpsave!=0 ) free(bmpsave);
478 : }
479 : else {
480 0 : ierr=13;
481 0 : return(ierr);
482 : }
483 : }
484 : else { // do not unpack bitmap
485 312 : gbit(cgrib,&lgfld->ibmap,iofst,8); // Get BitMap Indicator
486 312 : have6=1;
487 312 : if( lgfld->ibmap == 0 ) {
488 : /* Save the offset of this section in case we might need to unpack it later for a later subfield */
489 8 : iofst_last_sect6 = iofst;
490 : }
491 : }
492 : }
493 : //
494 : // If found Section 7, check to see if this field is the
495 : // one requested.
496 : //
497 2971 : if (isecnum==7 && numfld==ifldnum && unpack) {
498 163 : iofst=iofst-40; // reset offset to beginning of section
499 :
500 : /* If expand is requested and we cannot do it, then early exit */
501 : /* to avoid useless operations */
502 : /* Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2183 */
503 : /* See grib2api.c : */
504 : /* Check if NCEP had problems expanding the data. If so we currently
505 : * abort. May need to revisit this behavior. */
506 163 : if( expand )
507 : {
508 163 : if ( lgfld->ibmap != 255 && lgfld->bmap != 0 )
509 : {
510 2 : if( lgfld->ngrdpts < lgfld->ndpts )
511 : {
512 : /* There are more points in the data section than in */
513 : /* the bitmap, that doesn't make sense (bitmap only */
514 : /* makes sense if it saves the encoding of points in */
515 : /* the data section) */
516 0 : ierr=14;
517 0 : return(ierr);
518 : }
519 : }
520 161 : else if( lgfld->ngrdpts != lgfld->ndpts )
521 : {
522 0 : ierr=14;
523 0 : return(ierr);
524 : }
525 : }
526 :
527 163 : jerr=g2_unpack7(cgrib,cgrib_length,&iofst,lgfld->igdtnum,lgfld->igdtmpl,
528 : lgfld->idrtnum,lgfld->idrtmpl,lgfld->ndpts,
529 : &lgfld->fld);
530 163 : if (jerr == 0) {
531 163 : have7=1;
532 : // If bitmap is used with this field, expand data field
533 : // to grid, if possible.
534 163 : if ( lgfld->ibmap != 255 && lgfld->bmap != 0 ) {
535 2 : if ( expand == 1 ) {
536 2 : n=0;
537 2 : newfld=(g2float *)calloc(lgfld->ngrdpts,sizeof(g2float));
538 802 : for (j=0;j<lgfld->ngrdpts;j++) {
539 800 : if (lgfld->bmap[j]==1)
540 : {
541 800 : if( n >= lgfld->ndpts )
542 : {
543 0 : printf("g2_getfld: overflow of lgfld->fld array\n");
544 0 : ierr=14;
545 0 : free(newfld);
546 0 : return(ierr);
547 : }
548 800 : newfld[j]=lgfld->fld[n++];
549 : }
550 : }
551 2 : free(lgfld->fld);
552 2 : lgfld->fld=newfld;
553 2 : lgfld->expanded=1;
554 : }
555 : else {
556 0 : lgfld->expanded=0;
557 : }
558 : }
559 : else {
560 161 : if( lgfld->ngrdpts != lgfld->ndpts )
561 : {
562 : /* Added by E. Rouault to fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2070 */
563 0 : lgfld->expanded=0;
564 : }
565 : else
566 : {
567 161 : lgfld->expanded=1;
568 : }
569 : }
570 : }
571 : else {
572 0 : printf("g2_getfld: return from g2_unpack7 = %d \n",(int)jerr);
573 0 : ierr=14;
574 0 : return(ierr);
575 : }
576 : }
577 : //
578 : // Check to see if we read pass the end of the GRIB
579 : // message and missed the terminator string '7777'.
580 : //
581 2971 : ipos=ipos+lensec; // Update beginning of section pointer
582 2971 : if (ipos > (istart+lengrib)) {
583 0 : printf("g2_getfld: '7777' not found at end of GRIB message.\n");
584 0 : ierr=7;
585 0 : return(ierr);
586 : }
587 : //
588 : // If unpacking requested, return when all sections have been
589 : // processed
590 : //
591 2971 : if (unpack && have3 && have4 && have5 && have6 && have7)
592 163 : return(ierr);
593 : //
594 : // If unpacking is not requested, return when sections
595 : // 3 through 6 have been processed
596 : //
597 2808 : if ((! unpack) && have3 && have4 && have5 && have6)
598 309 : return(ierr);
599 :
600 : }
601 :
602 : //
603 : // If exited from above loop, the end of the GRIB message was reached
604 : // before the requested field was found.
605 : //
606 0 : printf("g2_getfld: GRIB message contained %d different fields.\n",numfld);
607 0 : printf("g2_getfld: The request was for field %d.\n",ifldnum);
608 0 : ierr=6;
609 :
610 0 : return(ierr);
611 :
612 : }
|