NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
g2_getfld.c
Go to the documentation of this file.
1
6#include "grib2_int.h"
7#include <stdio.h>
8#include <stdlib.h>
9
93g2_getfld(unsigned char *cgrib, g2int ifldnum, g2int unpack, g2int expand,
94 gribfield **gfld)
95{
96
97 g2int have3 = 0, have4 = 0, have5 = 0, have6 = 0, have7 = 0;
98 g2int numfld = 0, j, n, istart, iofst, ipos;
99 g2int disc, ver, lensec0, lengrib, lensec, isecnum;
100 g2int *igds;
101 g2int *bmpsave;
102 float *newfld;
103 gribfield *lgfld;
104 g2int jerr;
105
106 /* Allocate storage for the field struct. The caller must free
107 * this memory. */
108 lgfld = calloc(1, sizeof(gribfield));
109 *gfld = lgfld;
110
111 /* Check for valid request number. */
112 if (ifldnum <= 0)
113 {
114 printf("g2_getfld: Request for field number must be positive.\n");
115 free(lgfld);
116 return G2_GETFLD_INVAL;
117 }
118
119 /* Check for beginning of GRIB message in the first 100 bytes. */
120 istart = -1;
121 for (j = 0; j < 100; j++)
122 {
123 if (cgrib[j] == 'G' && cgrib[j + 1] == 'R' && cgrib[j + 2] == 'I' &&
124 cgrib[j + 3] == 'B')
125 {
126 istart = j;
127 break;
128 }
129 }
130 if (istart == -1)
131 {
132 printf("g2_getfld: Beginning characters GRIB not found.\n");
133 free(lgfld);
134 return G2_GETFLD_NO_GRIB;
135 }
136
137 /* Unpack Section 0 - Indicator Section. */
138 iofst = 8 * (istart + 6);
139 gbit(cgrib, &disc, iofst, 8); /* Discipline */
140 iofst = iofst + 8;
141 gbit(cgrib, &ver, iofst, 8); /* GRIB edition number */
142 iofst = iofst + 8;
143 iofst = iofst + 32;
144 gbit(cgrib, &lengrib, iofst, 32); /* Length of GRIB message */
145 iofst = iofst + 32;
146 lensec0 = 16;
147 ipos = istart + lensec0;
148
149 /* Currently handles only GRIB Edition 2. */
150 if (ver != 2)
151 {
152 printf("g2_getfld: can only decode GRIB edition 2.\n");
153 free(lgfld);
155 }
156
157 /* Loop through the remaining sections keeping track of the
158 * length of each. Also keep the latest Grid Definition Section
159 * info. Unpack the requested field number. */
160 for (;;)
161 {
162 /* Check to see if we are at end of GRIB message */
163 if (cgrib[ipos] == '7' && cgrib[ipos + 1] == '7' && cgrib[ipos + 2] == '7' &&
164 cgrib[ipos + 3] == '7')
165 {
166 ipos = ipos + 4;
167
168 /* If end of GRIB message not where expected, issue
169 * error. */
170 if (ipos != istart + lengrib)
171 {
172 printf("g2_getfld: '7777' found, but not where expected.\n");
173 free(lgfld);
174 return G2_GETFLD_WRONG_END;
175 }
176 break;
177 }
178
179 /* Get length of Section and Section number. */
180 iofst = ipos * 8;
181 gbit(cgrib, &lensec, iofst, 32); /* Get Length of Section */
182 iofst = iofst + 32;
183 gbit(cgrib, &isecnum, iofst, 8); /* Get Section number */
184 iofst = iofst + 8;
185
186 /* Check to see if section number is valid. */
187 if (isecnum < 1 || isecnum > 7)
188 {
189 printf("g2_getfld: Unrecognized Section Encountered=%ld\n", isecnum);
190 free(lgfld);
191 return G2_GETFLD_INVAL_SEC;
192 }
193
194 /* If found Section 1, decode elements in Identification Section. */
195 if (isecnum == 1)
196 {
197 iofst = iofst - 40; /* reset offset to beginning of section */
198 if (g2_unpack1(cgrib, &iofst, &lgfld->idsect, &lgfld->idsectlen))
199 {
200 g2_free(lgfld);
201 return G2_GETFLD_BAD_SEC1;
202 }
203 }
204
205 /* If found Section 2, Grab local section. Save in case this
206 * is the latest one before the requested field. */
207 if (isecnum == 2)
208 {
209 iofst = iofst - 40; /* reset offset to beginning of section */
210 if (lgfld->local)
211 free(lgfld->local);
212 if (g2_unpack2(cgrib, &iofst, &lgfld->locallen, &lgfld->local))
213 {
214 g2_free(lgfld);
215 return G2_GETFLD_BAD_SEC2;
216 }
217 }
218
219 /* If found Section 3, unpack the GDS info using the
220 * appropriate template. Save in case this is the latest grid
221 * before the requested field. */
222 if (isecnum == 3)
223 {
224 iofst = iofst - 40; /* reset offset to beginning of section */
225 if (lgfld->igdtmpl)
226 free(lgfld->igdtmpl);
227 if (lgfld->list_opt)
228 free(lgfld->list_opt);
229 if (g2_unpack3(cgrib, &iofst, &igds, &lgfld->igdtmpl,
230 &lgfld->igdtlen, &lgfld->list_opt, &lgfld->num_opt))
231 {
232 g2_free(lgfld);
233 return G2_GETFLD_BAD_SEC3;
234 }
235
236 have3 = 1;
237 lgfld->griddef = igds[0];
238 lgfld->ngrdpts = igds[1];
239 lgfld->numoct_opt = igds[2];
240 lgfld->interp_opt = igds[3];
241 lgfld->igdtnum = igds[4];
242 free(igds);
243 }
244
245 /* If found Section 4, check to see if this field is the one
246 * requested. */
247 if (isecnum == 4)
248 {
249 numfld = numfld + 1;
250 if (numfld == ifldnum)
251 {
252 lgfld->discipline = disc;
253 lgfld->version = ver;
254 lgfld->ifldnum = ifldnum;
255 lgfld->unpacked = unpack;
256 lgfld->expanded = 0;
257 iofst = iofst - 40; /* reset offset to beginning of section */
258 if (g2_unpack4(cgrib, &iofst, &lgfld->ipdtnum, &lgfld->ipdtmpl,
259 &lgfld->ipdtlen, &lgfld->coord_list, &lgfld->num_coord))
260 {
261 g2_free(lgfld);
262 return G2_GETFLD_BAD_SEC4;
263 }
264
265 have4 = 1;
266 }
267 }
268
269 /* If found Section 5, check to see if this field is the one
270 * requested. */
271 if (isecnum == 5 && numfld == ifldnum)
272 {
273 iofst = iofst - 40; /* reset offset to beginning of section */
274 if (g2_unpack5(cgrib, &iofst, &lgfld->ndpts, &lgfld->idrtnum,
275 &lgfld->idrtmpl, &lgfld->idrtlen))
276 {
277 g2_free(lgfld);
278 return G2_GETFLD_BAD_SEC5;
279 }
280
281 have5 = 1;
282 }
283
284 /* If found Section 6, Unpack bitmap. Save in case this is
285 * the latest bitmap before the requested field. */
286 if (isecnum == 6)
287 {
288 if (unpack)
289 { /* unpack bitmap */
290 iofst = iofst - 40; /* reset offset to beginning of section */
291 bmpsave = lgfld->bmap; /* save pointer to previous bitmap */
292 if (g2_unpack6(cgrib, &iofst, lgfld->ngrdpts, &lgfld->ibmap,
293 &lgfld->bmap))
294 {
295 g2_free(lgfld);
296 return G2_GETFLD_BAD_SEC6;
297 }
298
299 have6 = 1;
300 if (lgfld->ibmap == 254) /* use previously specified bitmap */
301 {
302 if (bmpsave)
303 lgfld->bmap = bmpsave;
304 else
305 {
306 printf("g2_getfld: Prev bit-map specified, but none exist.\n");
307 return G2_GETFLD_NO_BITMAP;
308 }
309 }
310 else /* get rid of it */
311 if (bmpsave)
312 free(bmpsave);
313 }
314 else
315 { /* do not unpack bitmap */
316 gbit(cgrib, &lgfld->ibmap, iofst, 8); /* Get BitMap Indicator */
317 have6 = 1;
318 }
319 }
320
321 /* If found Section 7, check to see if this field is the one
322 * requested. */
323 if (isecnum == 7 && numfld == ifldnum && unpack)
324 {
325 iofst = iofst - 40; /* reset offset to beginning of section */
326 if ((jerr = g2_unpack7(cgrib, &iofst, lgfld->igdtnum, lgfld->igdtmpl,
327 lgfld->idrtnum, lgfld->idrtmpl, lgfld->ndpts,
328 &lgfld->fld)))
329 {
330 printf("g2_getfld: return from g2_unpack7 = %d \n", (int)jerr);
331 g2_free(lgfld);
332 return G2_GETFLD_BAD_SEC7;
333 }
334
335 have7 = 1;
336
337 /* If bitmap is used with this field, expand data field */
338 /* to grid, if possible. */
339 if (lgfld->ibmap != 255 && lgfld->bmap != 0)
340 {
341 if (expand == 1)
342 {
343 n = 0;
344 newfld = calloc(lgfld->ngrdpts, sizeof(float));
345 for (j = 0; j < lgfld->ngrdpts; j++)
346 {
347 if (lgfld->bmap[j] == 1)
348 newfld[j] = lgfld->fld[n++];
349 }
350 free(lgfld->fld);
351 lgfld->fld = newfld;
352 lgfld->expanded = 1;
353 }
354 else
355 {
356 lgfld->expanded = 0;
357 }
358 }
359 else
360 {
361 lgfld->expanded = 1;
362 }
363 }
364
365 /* Check to see if we read pass the end of the GRIB message
366 * and missed the terminator string '7777'. */
367 ipos = ipos + lensec; /* Update beginning of section pointer */
368 if (ipos > istart + lengrib)
369 {
370 printf("g2_getfld: '7777' not found at end of GRIB message.\n");
371 g2_free(lgfld);
372 return G2_GETFLD_BAD_END;
373 }
374
375 /* If unpacking requested, return when all sections have been
376 * processed. */
377 if (unpack && have3 && have4 && have5 && have6 && have7)
378 return G2_NO_ERROR;
379
380 /* If unpacking is not requested, return when sections 3
381 * through 6 have been processed. */
382 if (!unpack && have3 && have4 && have5 && have6)
383 return G2_NO_ERROR;
384 }
385
386 /* If exited from above loop, the end of the GRIB message was
387 * reached before the requested field was found. */
388 printf("g2_getfld: GRIB message contained %ld different fields.\n", numfld);
389 printf("g2_getfld: The request was for field %ld.\n", ifldnum);
390 g2_free(lgfld);
392}
void g2_free(gribfield *gfld)
Free memory that was allocated for struct gribfield.
Definition g2_free.c:23
g2int g2_getfld(unsigned char *cgrib, g2int ifldnum, g2int unpack, g2int expand, gribfield **gfld)
Return all the metadata, template values, bit-map (if applicable), and the unpacked data for a data f...
Definition g2_getfld.c:93
g2int g2_unpack1(unsigned char *cgrib, g2int *iofst, g2int **ids, g2int *idslen)
Unpacks Section 1 - Identification Section of a GRIB2 message.
Definition g2_unpack1.c:55
g2int g2_unpack2(unsigned char *cgrib, g2int *iofst, g2int *lencsec2, unsigned char **csec2)
Unpack Section 2 (Local Use Section) of a GRIB2 message.
Definition g2_unpack2.c:37
g2int g2_unpack3(unsigned char *cgrib, g2int *iofst, g2int **igds, g2int **igdstmpl, g2int *mapgridlen, g2int **ideflist, g2int *idefnum)
Unpack Section 3 (Grid Definition Section) of a GRIB2 message.
Definition g2_unpack3.c:62
g2int g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl, g2int *mappdslen, float **coordlist, g2int *numcoord)
Unpack Section 4 (Product Definition Section) of a GRIB2 message.
Definition g2_unpack4.c:45
g2int g2_unpack5(unsigned char *cgrib, g2int *iofst, g2int *ndpts, g2int *idrsnum, g2int **idrstmpl, g2int *mapdrslen)
Unpack Section 5 (Data Representation Section) of a GRIB2 message.
Definition g2_unpack5.c:40
g2int g2_unpack6(unsigned char *cgrib, g2int *iofst, g2int ngpts, g2int *ibmap, g2int **bmap)
Unpack Section 6 (Bit-Map Section) of a GRIB2 message.
Definition g2_unpack6.c:32
g2int g2_unpack7(unsigned char *cgrib, g2int *iofst, g2int igdsnum, g2int *igdstmpl, g2int idrsnum, g2int *idrstmpl, g2int ndpts, float **fld)
This subroutine unpacks Section 7 (Data Section) of a GRIB2 message.
Definition g2_unpack7.c:214
void gbit(unsigned char *in, g2int *iout, g2int iskip, g2int nbits)
Get arbitrary size values from a packed bit string, right justifying each value in the unpacked iout ...
Definition gbits.c:20
g2int igdtnum
Grid Definition Template Number (See Table 3.1).
Definition grib2.h:148
g2int locallen
Length of array local.
Definition grib2.h:110
g2int ibmap
Bitmap indicator (see Table 6.0).
Definition grib2.h:211
#define G2_GETFLD_BAD_SEC7
Error in g2_getfld() unpacking section 7.
Definition grib2.h:445
g2int interp_opt
Interpretation of list for optional points definition.
Definition grib2.h:133
g2int ngrdpts
Number of grid points in the defined grid.
Definition grib2.h:123
#define G2_GETFLD_INVAL
g2_getfld() data field request number was not positive.
Definition grib2.h:433
g2int ifldnum
Field number within GRIB message.
Definition grib2.h:113
#define G2_GETFLD_GRIB_VERSION
Wrong GRIB version for g2_getfld(), must be 2.
Definition grib2.h:432
g2int griddef
Source of grid definition (see Table 3.0).
Definition grib2.h:120
g2int ipdtnum
Product Definition Template Number (see Table 4.0).
Definition grib2.h:160
g2int * ipdtmpl
Contains the data values for the Product Definition Template specified by ipdtnum.
Definition grib2.h:168
#define G2_GETFLD_WRONG_NFLDS
In g2_getfld() message did not contain the requested number of data fields.
Definition grib2.h:435
g2int discipline
Message Discipline (see Table 0.0).
Definition grib2.h:52
#define G2_GETFLD_BAD_SEC2
Error in g2_getfld() unpacking section 2.
Definition grib2.h:440
g2int numoct_opt
Number of octets needed for each additional grid points definition.
Definition grib2.h:128
#define G2_GETFLD_BAD_SEC1
Error in g2_getfld() unpacking section 1.
Definition grib2.h:439
#define G2_GETFLD_BAD_SEC5
Error in g2_getfld() unpacking section 5.
Definition grib2.h:443
g2int idrtlen
Number of elements in idrtmpl.
Definition grib2.h:186
g2int unpacked
Logical value indicating whether the bitmap and data values were unpacked.
Definition grib2.h:194
g2int idsectlen
Number of elements in idsect.
Definition grib2.h:103
g2int ipdtlen
Number of elements in ipdtmpl - i.e.
Definition grib2.h:164
#define G2_GETFLD_WRONG_END
g2_info() found "7777" not where expected.
Definition grib2.h:434
#define G2_GETFLD_BAD_SEC4
Error in g2_getfld() unpacking section 4.
Definition grib2.h:442
#define G2_NO_ERROR
Function succeeded.
Definition grib2.h:423
#define G2_GETFLD_NO_GRIB
g2_getfld() can't find beginning characters "GRIB".
Definition grib2.h:431
float * coord_list
Array containing floating point values intended to document the vertical discretisation associated to...
Definition grib2.h:176
g2int * igdtmpl
Contains the data values for the Grid Definition Template specified by igdtnum.
Definition grib2.h:156
g2int idrtnum
Data Representation Template Number (see Table 5.0).
Definition grib2.h:183
g2int ndpts
Number of data points unpacked and returned.
Definition grib2.h:179
g2int * idrtmpl
Contains the data values for the Data Representation Template specified by idrtnum.
Definition grib2.h:190
#define G2_GETFLD_BAD_SEC6
Error in g2_getfld() unpacking section 6.
Definition grib2.h:444
g2int * list_opt
(Used if numoct_opt .ne.
Definition grib2.h:144
g2int version
GRIB edition number (2).
Definition grib2.h:48
#define G2_GETFLD_BAD_SEC3
Error in g2_getfld() unpacking section 3.
Definition grib2.h:441
g2int * idsect
Contains the entries in the Identification Section (Section 1).
Definition grib2.h:100
float * fld
Array of ndpts unpacked data points.
Definition grib2.h:218
g2int num_coord
Number of values in array coord_list.
Definition grib2.h:171
unsigned char * local
Pointer to character array containing contents of Local Section 2, if included.
Definition grib2.h:107
#define G2_GETFLD_BAD_END
g2_getfld() didn't find "7777" at end of message.
Definition grib2.h:436
g2int expanded
Logical value indicating whether the data field was expanded to the grid in the case where a bit-map ...
Definition grib2.h:203
g2int num_opt
(Used if numoct_opt .ne.
Definition grib2.h:139
g2int igdtlen
Number of elements in igdtmpl - i.e.
Definition grib2.h:152
#define G2_GETFLD_NO_BITMAP
In g2_getfld() previous bitmap specified, yet none exists.
Definition grib2.h:446
g2int * bmap
Integer array containing decoded bitmap, if ibmap=0 or ibap=254.
Definition grib2.h:215
int64_t g2int
Long integer type.
Definition grib2.h:32
#define G2_GETFLD_INVAL_SEC
g2_getfld() encountered unrecognized section.
Definition grib2.h:437
Struct for GRIB2 field.
Definition grib2.h:46
Header file with internal function prototypes NCEPLIBS-g2c library.