NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
g2_addgrid.c
Go to the documentation of this file.
1
8#include "grib2_int.h"
9#include <stdio.h>
10#include <stdlib.h>
11
66g2_addgrid(unsigned char *cgrib, g2int *igds, g2int *igdstmpl, g2int *ideflist,
67 g2int idefnum)
68{
69 static g2int one = 1, three = 3, miss = 65535;
70 g2int lensec3, iofst, ibeg, lencurr, len;
71 g2int i, j, temp, ilen, isecnum, nbits;
72 gtemplate *mapgrid = 0;
73 int ret;
74
75 /* Check for GRIB header and terminator. Translate the error codes
76 * to the legacy G2 error codes. */
77 if ((ret = g2c_check_msg(cgrib, &lencurr, 1)))
78 {
79 if (ret == G2C_ENOTGRIB)
80 return G2_ADD_MSG_INIT;
81 if (ret == G2C_EMSGCOMPLETE)
83 }
84
85 /* Loop through all current sections of the GRIB message to find
86 * the last section number. */
87 len = 16; /* length of Section 0 */
88 for (;;)
89 {
90 /* Get section number and length of next section. */
91 iofst = len * 8;
92 gbit(cgrib, &ilen, iofst, 32);
93 iofst = iofst + 32;
94 gbit(cgrib, &isecnum, iofst, 8);
95 len = len + ilen;
96
97 /* Exit loop if last section reached. */
98 if (len == lencurr)
99 break;
100
101 /* If byte count for each section doesn't match current total
102 * length, then there is a problem. */
103 if (len > lencurr)
104 {
105 printf("g2_addgrid: Section byte counts don''t add to total.\n");
106 printf("g2_addgrid: Sum of section byte counts = %ld\n", len);
107 printf("g2_addgrid: Total byte count in Section 0 = %ld\n", lencurr);
108 return G2_BAD_SEC_COUNTS;
109 }
110 }
111
112 /* Section 3 can only be added after sections 1, 2 and 7. */
113 if (isecnum != 1 && isecnum != 2 && isecnum != 7)
114 {
115 printf("g2_addgrid: Section 3 can only be added after Section 1, 2 or 7.\n");
116 printf("g2_addgrid: Section ',isecnum,' was the last found in given GRIB message.\n");
117 return G2_BAD_SEC;
118 }
119
120 /* Add Section 3 - Grid Definition Section. */
121 ibeg = lencurr * 8; /* Calculate offset for beginning of section 3 */
122 iofst = ibeg + 32; /* leave space for length of section */
123 sbit(cgrib, &three, iofst, 8); /* Store section number (3) */
124 iofst = iofst + 8;
125 sbit(cgrib, igds + 0, iofst, 8); /* Store source of Grid def. */
126 iofst = iofst + 8;
127 sbit(cgrib, igds + 1, iofst, 32); /* Store number of data pts. */
128 iofst = iofst + 32;
129 sbit(cgrib, igds + 2, iofst, 8); /* Store number of extra octets. */
130 iofst = iofst + 8;
131 sbit(cgrib, igds + 3, iofst, 8); /* Store interp. of extra octets. */
132 iofst = iofst + 8;
133
134 /* if Octet 6 is not equal to zero, Grid Definition Template may
135 * not be supplied. */
136 if (igds[0] == 0)
137 sbit(cgrib, igds + 4, iofst, 16); /* Store Grid Def Template num. */
138 else
139 sbit(cgrib, &miss, iofst, 16); /* Store missing value as Grid Def Template num. */
140 iofst = iofst + 16;
141
142 /* Get Grid Definition Template. */
143 if (igds[0] == 0)
144 {
145 if (!(mapgrid = getgridtemplate(igds[4])))
146 return G2_ADDGRID_BAD_GDT;
147
148 /* Extend the Grid Definition Template, if necessary. The
149 * number of values in a specific template may vary depending
150 * on data specified in the "static" part of the template. */
151 if (mapgrid->needext)
152 {
153 free(mapgrid);
154 mapgrid = extgridtemplate(igds[4], igdstmpl);
155 }
156 }
157
158 /* Pack up each input value in array igdstmpl into the
159 * appropriate number of octets, which are specified in
160 * corresponding entries in array mapgrid. */
161 for (i = 0; i < mapgrid->maplen; i++)
162 {
163 nbits = abs(mapgrid->map[i]) * 8;
164 if ((mapgrid->map[i] >= 0) || (igdstmpl[i] >= 0))
165 sbit(cgrib, igdstmpl + i, iofst, nbits);
166 else
167 {
168 sbit(cgrib, &one, iofst, 1);
169 temp = abs(igdstmpl[i]);
170 sbit(cgrib, &temp, iofst + 1, nbits - 1);
171 }
172 iofst = iofst + nbits;
173 }
174
175 /* Pack template extension, if appropriate. */
176 j = mapgrid->maplen;
177 if (mapgrid->needext && mapgrid->extlen > 0)
178 {
179 for (i = 0; i < mapgrid->extlen; i++)
180 {
181 nbits = abs(mapgrid->ext[i]) * 8;
182 if (mapgrid->ext[i] >= 0 || igdstmpl[j] >= 0)
183 sbit(cgrib, igdstmpl + j, iofst, nbits);
184 else
185 {
186 sbit(cgrib, &one, iofst, 1);
187 temp = abs(igdstmpl[j]);
188 sbit(cgrib, &temp, iofst + 1, nbits - 1);
189 }
190 iofst = iofst + nbits;
191 j++;
192 }
193 }
194 if (mapgrid->ext)
195 free(mapgrid->ext);
196 free(mapgrid);
197
198 /* If requested, insert optional list of numbers defining number
199 * of points in each row or column. This is used for non regular
200 * grids. */
201 if (igds[2] != 0)
202 {
203 nbits = igds[2] * 8;
204 sbits(cgrib, ideflist, iofst, nbits, 0, idefnum);
205 iofst = iofst + (nbits * idefnum);
206 }
207
208 /* Calculate length of section 3 and store it in octets 1-4 of section 3. */
209 lensec3 = (iofst - ibeg) / 8;
210 sbit(cgrib, &lensec3, ibeg, 32);
211
212 /* Update current byte total of message in Section 0. */
213 lencurr += lensec3;
214 sbit(cgrib, &lencurr, 96, 32);
215
216 return lencurr;
217}
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
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
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
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
#define G2_BAD_SEC_COUNTS
Sum of Section byte counts doesn't add to total byte count.
Definition grib2.h:460
#define G2_BAD_SEC
Previous Section was unexpected.
Definition grib2.h:448
#define G2_ADDGRID_BAD_GDT
In g2_addgrid() Could not find requested Grid Definition Template.
Definition grib2.h:467
#define G2_ADD_MSG_COMPLETE
GRIB message already complete.
Definition grib2.h:459
#define G2_ADD_MSG_INIT
GRIB message was not initialized - call g2_create() first.
Definition grib2.h:458
#define G2C_ENOTGRIB
GRIB header not found.
Definition grib2.h:478
#define G2C_EMSGCOMPLETE
GRIB message already complete.
Definition grib2.h:479
int64_t g2int
Long integer type.
Definition grib2.h:32
Header file with internal function prototypes NCEPLIBS-g2c library.
g2int * ext
Number of octets of each entry in the extension part of the template.
Definition grib2_int.h:302
int g2c_check_msg(unsigned char *cgrib, g2int *lencurr, int verbose)
Check for 'GRIB' at the beginning of a GRIB message, and check to see if the message is already termi...
Definition util.c:26
g2int extlen
Number of entries in the template extension.
Definition grib2_int.h:298
g2int * map
Number of octets of each entry in the static part of the template.
Definition grib2_int.h:292
g2int needext
Indicates whether or not the template needs to be extended.
Definition grib2_int.h:295
gtemplate * extgridtemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Grid Definition Template,...
gtemplate * getgridtemplate(g2int number)
This subroutine returns grid template information for a specified Grid Definition Template for [Secti...
g2int maplen
Number of entries in the static part of the template.
Definition grib2_int.h:288
Struct for GRIB template, returned by getgridtemplate().
Definition grib2_int.h:278