Loading...
Searching...
No Matches
g2_addgrid.c
Go to the documentation of this file.
#include "grib2_int.h"
#include <stdio.h>
#include <stdlib.h>
g2int
g2_addgrid(unsigned char *cgrib, g2int *igds, g2int *igdstmpl, g2int *ideflist,
g2int idefnum)
{
static g2int one = 1, three = 3, miss = 65535;
g2int lensec3, iofst, ibeg, lencurr, len;
g2int i, j, temp, ilen, isecnum, nbits;
gtemplate *mapgrid = 0;
int ret;
/* Check for GRIB header and terminator. Translate the error codes
* to the legacy G2 error codes. */
if ((ret = g2c_check_msg(cgrib, &lencurr, 1, 2)))
{
if (ret == G2C_ENOTGRIB)
return G2_ADD_MSG_INIT;
if (ret == G2C_EMSGCOMPLETE)
return G2_ADD_MSG_COMPLETE;
}
/* Loop through all current sections of the GRIB message to find
* the last section number. */
len = 16; /* length of Section 0 */
for (;;)
{
/* Get section number and length of next section. */
iofst = len * 8;
gbit(cgrib, &ilen, iofst, 32);
iofst = iofst + 32;
gbit(cgrib, &isecnum, iofst, 8);
len = len + ilen;
/* Exit loop if last section reached. */
if (len == lencurr)
break;
/* If byte count for each section doesn't match current total
* length, then there is a problem. */
if (len > lencurr)
{
printf("g2_addgrid: Section byte counts don''t add to total.\n");
printf("g2_addgrid: Sum of section byte counts = %ld\n", len);
printf("g2_addgrid: Total byte count in Section 0 = %ld\n", lencurr);
return G2_BAD_SEC_COUNTS;
}
}
/* Section 3 can only be added after sections 1, 2 and 7. */
if (isecnum != 1 && isecnum != 2 && isecnum != 7)
{
printf("g2_addgrid: Section 3 can only be added after Section 1, 2 or 7.\n");
printf("g2_addgrid: Section ',isecnum,' was the last found in given GRIB message.\n");
return G2_BAD_SEC;
}
/* Add Section 3 - Grid Definition Section. */
ibeg = lencurr * 8; /* Calculate offset for beginning of section 3 */
iofst = ibeg + 32; /* leave space for length of section */
sbit(cgrib, &three, iofst, 8); /* Store section number (3) */
iofst = iofst + 8;
sbit(cgrib, igds + 0, iofst, 8); /* Store source of Grid def. */
iofst = iofst + 8;
sbit(cgrib, igds + 1, iofst, 32); /* Store number of data pts. */
iofst = iofst + 32;
sbit(cgrib, igds + 2, iofst, 8); /* Store number of extra octets. */
iofst = iofst + 8;
sbit(cgrib, igds + 3, iofst, 8); /* Store interp. of extra octets. */
iofst = iofst + 8;
/* if Octet 6 is not equal to zero, Grid Definition Template may
* not be supplied. */
if (igds[0] == 0)
sbit(cgrib, igds + 4, iofst, 16); /* Store Grid Def Template num. */
else
sbit(cgrib, &miss, iofst, 16); /* Store missing value as Grid Def Template num. */
iofst = iofst + 16;
/* Get Grid Definition Template. */
if (igds[0] == 0)
{
if (!(mapgrid = getgridtemplate(igds[4])))
return G2_ADDGRID_BAD_GDT;
/* Extend the Grid Definition Template, if necessary. The
* number of values in a specific template may vary depending
* on data specified in the "static" part of the template. */
if (mapgrid->needext)
{
free(mapgrid);
mapgrid = extgridtemplate(igds[4], igdstmpl);
}
}
/* Pack up each input value in array igdstmpl into the
* appropriate number of octets, which are specified in
* corresponding entries in array mapgrid. */
for (i = 0; i < mapgrid->maplen; i++)
{
nbits = abs(mapgrid->map[i]) * 8;
if ((mapgrid->map[i] >= 0) || (igdstmpl[i] >= 0))
sbit(cgrib, igdstmpl + i, iofst, nbits);
else
{
sbit(cgrib, &one, iofst, 1);
temp = abs(igdstmpl[i]);
sbit(cgrib, &temp, iofst + 1, nbits - 1);
}
iofst = iofst + nbits;
}
/* Pack template extension, if appropriate. */
j = mapgrid->maplen;
if (mapgrid->needext && mapgrid->extlen > 0)
{
for (i = 0; i < mapgrid->extlen; i++)
{
nbits = abs(mapgrid->ext[i]) * 8;
if (mapgrid->ext[i] >= 0 || igdstmpl[j] >= 0)
sbit(cgrib, igdstmpl + j, iofst, nbits);
else
{
sbit(cgrib, &one, iofst, 1);
temp = abs(igdstmpl[j]);
sbit(cgrib, &temp, iofst + 1, nbits - 1);
}
iofst = iofst + nbits;
j++;
}
}
if (mapgrid->ext)
free(mapgrid->ext);
free(mapgrid);
/* If requested, insert optional list of numbers defining number
* of points in each row or column. This is used for non regular
* grids. */
if (igds[2] != 0)
{
nbits = igds[2] * 8;
sbits(cgrib, ideflist, iofst, nbits, 0, idefnum);
iofst = iofst + (nbits * idefnum);
}
/* Calculate length of section 3 and store it in octets 1-4 of section 3. */
lensec3 = (iofst - ibeg) / 8;
sbit(cgrib, &lensec3, ibeg, 32);
/* Update current byte total of message in Section 0. */
lencurr += lensec3;
sbit(cgrib, &lencurr, 96, 32);
return lencurr;
}
g2_addgrid
g2int g2_addgrid(unsigned char *cgrib, g2int *igds, g2int *igdstmpl, g2int *ideflist, g2int idefnum)
Packs a Grid Definition Section (Section 3) and adds it to a GRIB2 message.
Definition g2_addgrid.c:66
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
sbits
void sbits(unsigned char *out, g2int *in, g2int iskip, g2int nbits, g2int nskip, g2int n)
Store arbitrary size values into a packed bit string, taking the low order bits from each value in th...
Definition gbits.c:178
sbit
void sbit(unsigned char *out, g2int *in, g2int iskip, g2int nbits)
Store arbitrary size values into a packed bit string, taking the low order bits from each value in th...
Definition gbits.c:38
G2_BAD_SEC_COUNTS
#define G2_BAD_SEC_COUNTS
Sum of Section byte counts doesn't add to total byte count.
Definition grib2.h:474
G2_BAD_SEC
#define G2_BAD_SEC
Previous Section was unexpected.
Definition grib2.h:462
G2_ADDGRID_BAD_GDT
#define G2_ADDGRID_BAD_GDT
In g2_addgrid() Could not find requested Grid Definition Template.
Definition grib2.h:481
G2_ADD_MSG_COMPLETE
#define G2_ADD_MSG_COMPLETE
GRIB message already complete.
Definition grib2.h:473
G2_ADD_MSG_INIT
#define G2_ADD_MSG_INIT
GRIB message was not initialized - call g2_create() first.
Definition grib2.h:472
G2C_ENOTGRIB
#define G2C_ENOTGRIB
GRIB header not found.
Definition grib2.h:492
G2C_EMSGCOMPLETE
#define G2C_EMSGCOMPLETE
GRIB message already complete.
Definition grib2.h:493
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
extgridtemplate
gtemplate * extgridtemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Grid Definition Template,...
Definition gridtemplates.c:241
g2c_check_msg
int g2c_check_msg(unsigned char *cgrib, g2int *lencurr, int verbose, int from)
Check for 'GRIB' at the beginning of a GRIB message, and check to see if the message is already termi...
Definition util.c:41
getgridtemplate
gtemplate * getgridtemplate(g2int number)
This subroutine returns grid template information for a specified Grid Definition Template for [Secti...
Definition gridtemplates.c:193
gtemplate::maplen
g2int maplen
Number of entries in the static part of the template.
Definition grib2_int.h:288
gtemplate
Struct for GRIB template, returned by getgridtemplate().
Definition grib2_int.h:278