Loading...
Searching...
No Matches
g2_unpack4.c
Go to the documentation of this file.
#include "grib2_int.h"
#include <stdio.h>
#include <stdlib.h>
g2int
g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl,
g2int *mappdslen, float **coordlist, g2int *numcoord)
{
g2int needext, i, j, nbits, isecnum;
g2int lensec, isign, newlen;
g2int *coordieee;
g2int *lipdstmpl = 0;
float *lcoordlist;
gtemplate *mappds;
*ipdstmpl = NULL;
*coordlist = NULL;
gbit(cgrib, &lensec, *iofst, 32); /* Get Length of Section */
*iofst = *iofst + 32;
gbit(cgrib, &isecnum, *iofst, 8); /* Get Section Number */
*iofst = *iofst + 8;
if (isecnum != 4)
{
*numcoord = 0;
*mappdslen = 0;
return G2_UNPACK_BAD_SEC;
}
gbit(cgrib, numcoord, *iofst, 16); /* Get num of coordinate values */
*iofst = *iofst + 16;
gbit(cgrib, ipdsnum, *iofst, 16); /* Get Prod. Def Template num. */
*iofst = *iofst + 16;
/* Get Product Definition Template */
if (!(mappds = getpdstemplate(*ipdsnum)))
{
*mappdslen = 0;
return G2_UNPACK4_BAD_PDT;
}
*mappdslen = mappds->maplen;
needext = mappds->needext;
/* Unpack each value into array ipdstmpl from the the
* appropriate number of octets, which are specified in
* corresponding entries in array mappds. */
if (*mappdslen > 0)
lipdstmpl = calloc(*mappdslen, sizeof(g2int));
if (!lipdstmpl)
{
*mappdslen = 0;
*ipdstmpl = NULL;
if (mappds)
free(mappds);
return G2_UNPACK_NO_MEM;
}
*ipdstmpl = lipdstmpl;
for (i = 0; i < mappds->maplen; i++)
{
nbits = abs(mappds->map[i]) * 8;
if (mappds->map[i] >= 0)
{
gbit(cgrib, lipdstmpl + i, *iofst, nbits);
}
else
{
gbit(cgrib, &isign, *iofst, 1);
gbit(cgrib, lipdstmpl + i, *iofst + 1, nbits - 1);
if (isign == 1)
lipdstmpl[i] = -1 * lipdstmpl[i];
}
*iofst = *iofst + nbits;
}
/* Check to see if the Product Definition Template needs to be
* extended. The number of values in a specific template may
* vary depending on data specified in the "static" part of the
* gtemplate. */
if (needext == 1)
{
free(mappds);
mappds = extpdstemplate(*ipdsnum, lipdstmpl);
newlen = mappds->maplen + mappds->extlen;
lipdstmpl = realloc(lipdstmpl, newlen * sizeof(g2int));
*ipdstmpl = lipdstmpl;
/* Unpack the rest of the Product Definition Template */
j = 0;
for (i = *mappdslen; i < newlen; i++)
{
nbits = abs(mappds->ext[j]) * 8;
if (mappds->ext[j] >= 0)
{
gbit(cgrib, lipdstmpl + i, *iofst, nbits);
}
else
{
gbit(cgrib, &isign, *iofst, 1);
gbit(cgrib, lipdstmpl + i, *iofst + 1, nbits - 1);
if (isign == 1)
lipdstmpl[i] = -1 * lipdstmpl[i];
}
*iofst = *iofst + nbits;
j++;
}
*mappdslen = newlen;
}
if (mappds->ext)
free(mappds->ext);
if (mappds)
free(mappds);
/* Get Optional list of vertical coordinate values after the
* Product Definition Template, if necessary. */
*coordlist = NULL;
if (*numcoord != 0)
{
coordieee = calloc(*numcoord, sizeof(g2int));
lcoordlist = calloc(*numcoord, sizeof(float));
if (coordieee == 0 || lcoordlist == 0)
{
*numcoord = 0;
*coordlist = NULL;
if (coordieee)
free(coordieee);
if (lcoordlist)
free(lcoordlist);
return G2_UNPACK_NO_MEM;
}
else
{
*coordlist = lcoordlist;
}
gbits(cgrib, coordieee, *iofst, 32, 0, *numcoord);
rdieee(coordieee, *coordlist, *numcoord);
free(coordieee);
*iofst = *iofst + (32 * (*numcoord));
}
return G2_NO_ERROR;
}
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
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
gbits
void gbits(unsigned char *in, g2int *iout, g2int iskip, g2int nbits, g2int nskip, g2int n)
Unpack arbitrary size values from a packed bit string, right justifying each value in the unpacked io...
Definition gbits.c:57
G2_UNPACK_BAD_SEC
#define G2_UNPACK_BAD_SEC
Bad section number in unpacking function.
Definition grib2.h:457
G2_UNPACK4_BAD_PDT
#define G2_UNPACK4_BAD_PDT
In g2_unpack4(), undefined Product Definition Template.
Definition grib2.h:460
G2_UNPACK_NO_MEM
#define G2_UNPACK_NO_MEM
Error allocating memory in unpack function.
Definition grib2.h:458
G2_NO_ERROR
#define G2_NO_ERROR
Function succeeded.
Definition grib2.h:431
g2int
int64_t g2int
Long integer type.
Definition grib2.h:32
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.
gtemplate::ext
g2int * ext
Number of octets of each entry in the extension part of the template.
Definition grib2_int.h:302
gtemplate::extlen
g2int extlen
Number of entries in the template extension.
Definition grib2_int.h:298
gtemplate::map
g2int * map
Number of octets of each entry in the static part of the template.
Definition grib2_int.h:292
gtemplate::needext
g2int needext
Indicates whether or not the template needs to be extended.
Definition grib2_int.h:295
extpdstemplate
gtemplate * extpdstemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Product Definition Template,...
Definition pdstemplates.c:553
getpdstemplate
gtemplate * getpdstemplate(g2int number)
This subroutine returns PDS template information for a specified Product Definition Template.
Definition pdstemplates.c:504
gtemplate::maplen
g2int maplen
Number of entries in the static part of the template.
Definition grib2_int.h:288
rdieee
void rdieee(g2int *rieee, float *a, g2int num)
Read a list of real values in 32-bit IEEE floating point format.
Definition rdieee.c:20
gtemplate
Struct for GRIB template, returned by getgridtemplate().
Definition grib2_int.h:278