Loading...
Searching...
No Matches
g2_getfld.c
Go to the documentation of this file.
#include "grib2_int.h"
#include <stdio.h>
#include <stdlib.h>
g2int
g2_getfld(unsigned char *cgrib, g2int ifldnum, g2int unpack, g2int expand,
gribfield **gfld)
{
g2int have3 = 0, have4 = 0, have5 = 0, have6 = 0, have7 = 0;
g2int numfld = 0, j, n, istart, iofst, ipos;
g2int disc, ver, lensec0, lengrib, lensec, isecnum;
g2int *igds;
g2int *bmpsave;
float *newfld;
gribfield *lgfld;
g2int jerr;
/* Allocate storage for the field struct. The caller must free
* this memory. */
lgfld = calloc(1, sizeof(gribfield));
*gfld = lgfld;
/* Check for valid request number. */
if (ifldnum <= 0)
{
printf("g2_getfld: Request for field number must be positive.\n");
free(lgfld);
return G2_GETFLD_INVAL;
}
/* Check for beginning of GRIB message in the first 100 bytes. */
istart = -1;
for (j = 0; j < 100; j++)
{
if (cgrib[j] == 'G' && cgrib[j + 1] == 'R' && cgrib[j + 2] == 'I' &&
cgrib[j + 3] == 'B')
{
istart = j;
break;
}
}
if (istart == -1)
{
printf("g2_getfld: Beginning characters GRIB not found.\n");
free(lgfld);
return G2_GETFLD_NO_GRIB;
}
/* Unpack Section 0 - Indicator Section. */
iofst = 8 * (istart + 6);
gbit(cgrib, &disc, iofst, 8); /* Discipline */
iofst = iofst + 8;
gbit(cgrib, &ver, iofst, 8); /* GRIB edition number */
iofst = iofst + 8;
iofst = iofst + 32;
gbit(cgrib, &lengrib, iofst, 32); /* Length of GRIB message */
iofst = iofst + 32;
lensec0 = 16;
ipos = istart + lensec0;
/* Currently handles only GRIB Edition 2. */
if (ver != 2)
{
printf("g2_getfld: can only decode GRIB edition 2.\n");
free(lgfld);
return G2_GETFLD_GRIB_VERSION;
}
/* Loop through the remaining sections keeping track of the
* length of each. Also keep the latest Grid Definition Section
* info. Unpack the requested field number. */
for (;;)
{
/* Check to see if we are at end of GRIB message */
if (cgrib[ipos] == '7' && cgrib[ipos + 1] == '7' && cgrib[ipos + 2] == '7' &&
cgrib[ipos + 3] == '7')
{
ipos = ipos + 4;
/* If end of GRIB message not where expected, issue
* error. */
if (ipos != istart + lengrib)
{
printf("g2_getfld: '7777' found, but not where expected.\n");
free(lgfld);
return G2_GETFLD_WRONG_END;
}
break;
}
/* Get length of Section and Section number. */
iofst = ipos * 8;
gbit(cgrib, &lensec, iofst, 32); /* Get Length of Section */
iofst = iofst + 32;
gbit(cgrib, &isecnum, iofst, 8); /* Get Section number */
iofst = iofst + 8;
/* Check to see if section number is valid. */
if (isecnum < 1 || isecnum > 7)
{
printf("g2_getfld: Unrecognized Section Encountered=%ld\n", isecnum);
free(lgfld);
return G2_GETFLD_INVAL_SEC;
}
/* If found Section 1, decode elements in Identification Section. */
if (isecnum == 1)
{
iofst = iofst - 40; /* reset offset to beginning of section */
if (g2_unpack1(cgrib, &iofst, &lgfld->idsect, &lgfld->idsectlen))
{
g2_free(lgfld);
return G2_GETFLD_BAD_SEC1;
}
}
/* If found Section 2, Grab local section. Save in case this
* is the latest one before the requested field. */
if (isecnum == 2)
{
iofst = iofst - 40; /* reset offset to beginning of section */
if (lgfld->local)
free(lgfld->local);
if (g2_unpack2(cgrib, &iofst, &lgfld->locallen, &lgfld->local))
{
g2_free(lgfld);
return G2_GETFLD_BAD_SEC2;
}
}
/* If found Section 3, unpack the GDS info using the
* appropriate template. Save in case this is the latest grid
* before the requested field. */
if (isecnum == 3)
{
iofst = iofst - 40; /* reset offset to beginning of section */
if (lgfld->igdtmpl)
free(lgfld->igdtmpl);
if (lgfld->list_opt)
free(lgfld->list_opt);
if (g2_unpack3(cgrib, &iofst, &igds, &lgfld->igdtmpl,
&lgfld->igdtlen, &lgfld->list_opt, &lgfld->num_opt))
{
g2_free(lgfld);
return G2_GETFLD_BAD_SEC3;
}
have3 = 1;
lgfld->griddef = igds[0];
lgfld->ngrdpts = igds[1];
lgfld->numoct_opt = igds[2];
lgfld->interp_opt = igds[3];
lgfld->igdtnum = igds[4];
free(igds);
}
/* If found Section 4, check to see if this field is the one
* requested. */
if (isecnum == 4)
{
numfld = numfld + 1;
if (numfld == ifldnum)
{
lgfld->discipline = disc;
lgfld->version = ver;
lgfld->ifldnum = ifldnum;
lgfld->unpacked = unpack;
lgfld->expanded = 0;
iofst = iofst - 40; /* reset offset to beginning of section */
if (g2_unpack4(cgrib, &iofst, &lgfld->ipdtnum, &lgfld->ipdtmpl,
&lgfld->ipdtlen, &lgfld->coord_list, &lgfld->num_coord))
{
g2_free(lgfld);
return G2_GETFLD_BAD_SEC4;
}
have4 = 1;
}
}
/* If found Section 5, check to see if this field is the one
* requested. */
if (isecnum == 5 && numfld == ifldnum)
{
iofst = iofst - 40; /* reset offset to beginning of section */
if (g2_unpack5(cgrib, &iofst, &lgfld->ndpts, &lgfld->idrtnum,
&lgfld->idrtmpl, &lgfld->idrtlen))
{
g2_free(lgfld);
return G2_GETFLD_BAD_SEC5;
}
have5 = 1;
}
/* If found Section 6, Unpack bitmap. Save in case this is
* the latest bitmap before the requested field. */
if (isecnum == 6)
{
if (unpack)
{ /* unpack bitmap */
iofst = iofst - 40; /* reset offset to beginning of section */
bmpsave = lgfld->bmap; /* save pointer to previous bitmap */
if (g2_unpack6(cgrib, &iofst, lgfld->ngrdpts, &lgfld->ibmap,
&lgfld->bmap))
{
g2_free(lgfld);
return G2_GETFLD_BAD_SEC6;
}
have6 = 1;
if (lgfld->ibmap == 254) /* use previously specified bitmap */
{
if (bmpsave)
lgfld->bmap = bmpsave;
else
{
printf("g2_getfld: Prev bit-map specified, but none exist.\n");
return G2_GETFLD_NO_BITMAP;
}
}
else /* get rid of it */
if (bmpsave)
free(bmpsave);
}
else
{ /* do not unpack bitmap */
gbit(cgrib, &lgfld->ibmap, iofst, 8); /* Get BitMap Indicator */
have6 = 1;
}
}
/* If found Section 7, check to see if this field is the one
* requested. */
if (isecnum == 7 && numfld == ifldnum && unpack)
{
iofst = iofst - 40; /* reset offset to beginning of section */
if ((jerr = g2_unpack7(cgrib, &iofst, lgfld->igdtnum, lgfld->igdtmpl,
lgfld->idrtnum, lgfld->idrtmpl, lgfld->ndpts,
&lgfld->fld)))
{
printf("g2_getfld: return from g2_unpack7 = %d \n", (int)jerr);
g2_free(lgfld);
return G2_GETFLD_BAD_SEC7;
}
have7 = 1;
/* If bitmap is used with this field, expand data field */
/* to grid, if possible. */
if (lgfld->ibmap != 255 && lgfld->bmap != 0)
{
if (expand == 1)
{
n = 0;
newfld = calloc(lgfld->ngrdpts, sizeof(float));
for (j = 0; j < lgfld->ngrdpts; j++)
{
if (lgfld->bmap[j] == 1)
newfld[j] = lgfld->fld[n++];
}
free(lgfld->fld);
lgfld->fld = newfld;
lgfld->expanded = 1;
}
else
{
lgfld->expanded = 0;
}
}
else
{
lgfld->expanded = 1;
}
}
/* Check to see if we read pass the end of the GRIB message
* and missed the terminator string '7777'. */
ipos = ipos + lensec; /* Update beginning of section pointer */
if (ipos > istart + lengrib)
{
printf("g2_getfld: '7777' not found at end of GRIB message.\n");
g2_free(lgfld);
return G2_GETFLD_BAD_END;
}
/* If unpacking requested, return when all sections have been
* processed. */
if (unpack && have3 && have4 && have5 && have6 && have7)
return G2_NO_ERROR;
/* If unpacking is not requested, return when sections 3
* through 6 have been processed. */
if (!unpack && have3 && have4 && have5 && have6)
return G2_NO_ERROR;
}
/* If exited from above loop, the end of the GRIB message was
* reached before the requested field was found. */
printf("g2_getfld: GRIB message contained %ld different fields.\n", numfld);
printf("g2_getfld: The request was for field %ld.\n", ifldnum);
g2_free(lgfld);
return G2_GETFLD_WRONG_NFLDS;
}
g2_free
void g2_free(gribfield *gfld)
Free memory that was allocated for struct gribfield.
Definition g2_free.c:23
g2_getfld
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
g2_unpack1
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
g2_unpack2
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
g2_unpack3
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
g2_unpack4
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
g2_unpack5
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
g2_unpack6
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
g2_unpack7
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
gbit
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
gribfield::igdtnum
g2int igdtnum
Grid Definition Template Number (See Table 3.1).
Definition grib2.h:148
gribfield::locallen
g2int locallen
Length of array local.
Definition grib2.h:110
gribfield::ibmap
g2int ibmap
Bitmap indicator (see Table 6.0).
Definition grib2.h:211
G2_GETFLD_BAD_SEC7
#define G2_GETFLD_BAD_SEC7
Error in g2_getfld() unpacking section 7.
Definition grib2.h:459
gribfield::interp_opt
g2int interp_opt
Interpretation of list for optional points definition.
Definition grib2.h:133
gribfield::ngrdpts
g2int ngrdpts
Number of grid points in the defined grid.
Definition grib2.h:123
G2_GETFLD_INVAL
#define G2_GETFLD_INVAL
g2_getfld() data field request number was not positive.
Definition grib2.h:447
gribfield::ifldnum
g2int ifldnum
Field number within GRIB message.
Definition grib2.h:113
G2_GETFLD_GRIB_VERSION
#define G2_GETFLD_GRIB_VERSION
Wrong GRIB version for g2_getfld(), must be 2.
Definition grib2.h:446
gribfield::griddef
g2int griddef
Source of grid definition (see Table 3.0).
Definition grib2.h:120
gribfield::ipdtnum
g2int ipdtnum
Product Definition Template Number (see Table 4.0).
Definition grib2.h:160
gribfield::ipdtmpl
g2int * ipdtmpl
Contains the data values for the Product Definition Template specified by ipdtnum.
Definition grib2.h:168
G2_GETFLD_WRONG_NFLDS
#define G2_GETFLD_WRONG_NFLDS
In g2_getfld() message did not contain the requested number of data fields.
Definition grib2.h:449
gribfield::discipline
g2int discipline
Message Discipline (see Table 0.0).
Definition grib2.h:52
G2_GETFLD_BAD_SEC2
#define G2_GETFLD_BAD_SEC2
Error in g2_getfld() unpacking section 2.
Definition grib2.h:454
gribfield::numoct_opt
g2int numoct_opt
Number of octets needed for each additional grid points definition.
Definition grib2.h:128
G2_GETFLD_BAD_SEC1
#define G2_GETFLD_BAD_SEC1
Error in g2_getfld() unpacking section 1.
Definition grib2.h:453
G2_GETFLD_BAD_SEC5
#define G2_GETFLD_BAD_SEC5
Error in g2_getfld() unpacking section 5.
Definition grib2.h:457
gribfield::idrtlen
g2int idrtlen
Number of elements in idrtmpl.
Definition grib2.h:186
gribfield::unpacked
g2int unpacked
Logical value indicating whether the bitmap and data values were unpacked.
Definition grib2.h:194
gribfield::idsectlen
g2int idsectlen
Number of elements in idsect.
Definition grib2.h:103
gribfield::ipdtlen
g2int ipdtlen
Number of elements in ipdtmpl - i.e.
Definition grib2.h:164
G2_GETFLD_WRONG_END
#define G2_GETFLD_WRONG_END
g2_info() found "7777" not where expected.
Definition grib2.h:448
G2_GETFLD_BAD_SEC4
#define G2_GETFLD_BAD_SEC4
Error in g2_getfld() unpacking section 4.
Definition grib2.h:456
G2_NO_ERROR
#define G2_NO_ERROR
Function succeeded.
Definition grib2.h:437
G2_GETFLD_NO_GRIB
#define G2_GETFLD_NO_GRIB
g2_getfld() can't find beginning characters "GRIB".
Definition grib2.h:445
gribfield::coord_list
float * coord_list
Array containing floating point values intended to document the vertical discretisation associated to...
Definition grib2.h:176
gribfield::igdtmpl
g2int * igdtmpl
Contains the data values for the Grid Definition Template specified by igdtnum.
Definition grib2.h:156
gribfield::idrtnum
g2int idrtnum
Data Representation Template Number (see Table 5.0).
Definition grib2.h:183
gribfield::ndpts
g2int ndpts
Number of data points unpacked and returned.
Definition grib2.h:179
gribfield::idrtmpl
g2int * idrtmpl
Contains the data values for the Data Representation Template specified by idrtnum.
Definition grib2.h:190
G2_GETFLD_BAD_SEC6
#define G2_GETFLD_BAD_SEC6
Error in g2_getfld() unpacking section 6.
Definition grib2.h:458
gribfield::list_opt
g2int * list_opt
(Used if numoct_opt .ne.
Definition grib2.h:144
gribfield::version
g2int version
GRIB edition number (2).
Definition grib2.h:48
G2_GETFLD_BAD_SEC3
#define G2_GETFLD_BAD_SEC3
Error in g2_getfld() unpacking section 3.
Definition grib2.h:455
gribfield::idsect
g2int * idsect
Contains the entries in the Identification Section (Section 1).
Definition grib2.h:100
gribfield::fld
float * fld
Array of ndpts unpacked data points.
Definition grib2.h:218
gribfield::num_coord
g2int num_coord
Number of values in array coord_list.
Definition grib2.h:171
gribfield::local
unsigned char * local
Pointer to character array containing contents of Local Section 2, if included.
Definition grib2.h:107
G2_GETFLD_BAD_END
#define G2_GETFLD_BAD_END
g2_getfld() didn't find "7777" at end of message.
Definition grib2.h:450
gribfield::expanded
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
gribfield::num_opt
g2int num_opt
(Used if numoct_opt .ne.
Definition grib2.h:139
gribfield::igdtlen
g2int igdtlen
Number of elements in igdtmpl - i.e.
Definition grib2.h:152
G2_GETFLD_NO_BITMAP
#define G2_GETFLD_NO_BITMAP
In g2_getfld() previous bitmap specified, yet none exists.
Definition grib2.h:460
gribfield::bmap
g2int * bmap
Integer array containing decoded bitmap, if ibmap=0 or ibap=254.
Definition grib2.h:215
g2int
int64_t g2int
Long integer type.
Definition grib2.h:32
G2_GETFLD_INVAL_SEC
#define G2_GETFLD_INVAL_SEC
g2_getfld() encountered unrecognized section.
Definition grib2.h:451
gribfield
Struct for GRIB2 field.
Definition grib2.h:46
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.