NCEPLIBS-g2c 2.1.0
Loading...
Searching...
No Matches
g2_addfield.c
Go to the documentation of this file.
1
7#include "grib2_int.h"
8#include <stdio.h>
9#include <stdlib.h>
10
100g2_addfield(unsigned char *cgrib, g2int ipdsnum, g2int *ipdstmpl,
101 float *coordlist, g2int numcoord, g2int idrsnum, g2int *idrstmpl,
102 float *fld, g2int ngrdpts, g2int ibmap, g2int *bmap)
103{
104 unsigned char *cpack;
105 static g2int zero = 0, one = 1, four = 4, five = 5, six = 6, seven = 7;
106 const g2int minsize = 50000;
107 g2int iofst, ibeg, lencurr, len, nsize;
108 g2int ilen, isecnum, i, nbits, temp, left;
109 g2int ibmprev, j, lcpack, ioctet, newlen, ndpts;
110 g2int lensec4, lensec5, lensec6, lensec7;
111 g2int issec3 = 0, isprevbmap = 0, lpos3 = 0, JJ, KK, MM;
112 g2int *coordieee;
113 float *pfld;
114 gtemplate *mappds, *mapdrs;
115#if defined USE_PNG || defined USE_JPEG2000 || defined USE_OPENJPEG || defined USE_AEC
116 unsigned int allones = 4294967295u;
117 g2int width, height, iscan, itemp;
118#endif
119 int ret;
120
121 /* Check for GRIB header and terminator. Translate the error codes
122 * to the legacy G2 error codes. */
123 if ((ret = g2c_check_msg(cgrib, &lencurr, 1)))
124 {
125 if (ret == G2C_ENOTGRIB)
126 return G2_ADD_MSG_INIT;
127 if (ret == G2C_EMSGCOMPLETE)
128 return G2_ADD_MSG_COMPLETE;
129 }
130
131 /* Loop through all current sections of the GRIB message to find
132 * the last section number. */
133 len = 16; /* length of Section 0 */
134 for (;;)
135 {
136 /* Get number and length of next section. */
137 iofst = len * 8;
138 gbit(cgrib, &ilen, iofst, 32);
139 iofst = iofst + 32;
140 gbit(cgrib, &isecnum, iofst, 8);
141 iofst = iofst + 8;
142
143 /* Check if previous Section 3 exists. */
144 if (isecnum == 3)
145 {
146 issec3 = 1;
147 lpos3 = len;
148 }
149 /* Check if a previous defined bitmap exists. */
150 if (isecnum == 6)
151 {
152 gbit(cgrib, &ibmprev, iofst, 8);
153 iofst = iofst + 8;
154 if (ibmprev >= 0 && ibmprev <= 253)
155 isprevbmap = 1;
156 }
157 len = len + ilen;
158
159 /* Exit loop if last section reached. */
160 if (len == lencurr)
161 break;
162
163 /* If byte count for each section doesn't match current */
164 /* total length, then there is a problem. */
165 if (len > lencurr)
166 {
167 printf("g2_addfield: Section byte counts don''t add to total.\n");
168 printf("g2_addfield: Sum of section byte counts = %ld\n", len);
169 printf("g2_addfield: Total byte count in Section 0 = %ld\n", lencurr);
170 return G2_BAD_SEC_COUNTS;
171 }
172 }
173
174 /* Sections 4 through 7 can only be added after section 3 or 7. */
175 if (isecnum != 3 && isecnum != 7)
176 {
177 printf("g2_addfield: Sections 4-7 can only be added after Section 3 or 7.\n");
178 printf("g2_addfield: Section %ld was the last found in given GRIB message.\n",
179 isecnum);
180 return G2_BAD_SEC;
181 }
182 else if (!issec3)
183 {
184 /* Sections 4 through 7 can only be added if section 3 was previously defined. */
185 printf("g2_addfield: Sections 4-7 can only be added if Section 3 was previously included.\n");
186 printf("g2_addfield: Section 3 was not found in given GRIB message.\n");
187 printf("g2_addfield: Call to routine addgrid required to specify Grid definition.\n");
188 return G2_ADDFIELD_BAD_GDS;
189 }
190
191 /* Add Section 4 - Product Definition Section. */
192 ibeg = lencurr * 8; /* Calculate offset for beginning of section 4 */
193 iofst = ibeg + 32; /* leave space for length of section */
194 sbit(cgrib, &four, iofst, 8); /* Store section number (4) */
195 iofst = iofst + 8;
196 sbit(cgrib, &numcoord, iofst, 16); /* Store num of coordinate values */
197 iofst = iofst + 16;
198 sbit(cgrib, &ipdsnum, iofst, 16); /* Store Prod Def Template num. */
199 iofst = iofst + 16;
200
201 /* Get Product Definition Template. */
202 if (!(mappds = getpdstemplate(ipdsnum)))
203 return G2_ADDFIELD_BAD_PDT;
204
205 /* Extend the Product Definition Template, if necessary. The */
206 /* number of values in a specific template may vary depending on */
207 /* data specified in the "static" part of the template. */
208 if (mappds->needext)
209 {
210 free(mappds);
211 mappds = extpdstemplate(ipdsnum, ipdstmpl);
212 }
213
214 /* Pack up each input value in array ipdstmpl into the the */
215 /* appropriate number of octets, which are specified in */
216 /* corresponding entries in array mappds. */
217 for (i = 0; i < mappds->maplen; i++)
218 {
219 nbits = abs(mappds->map[i]) * 8;
220 if ((mappds->map[i] >= 0) || (ipdstmpl[i] >= 0))
221 sbit(cgrib, ipdstmpl + i, iofst, nbits);
222 else
223 {
224 sbit(cgrib, &one, iofst, 1);
225 temp = abs(ipdstmpl[i]);
226 sbit(cgrib, &temp, iofst + 1, nbits - 1);
227 }
228 iofst = iofst + nbits;
229 }
230
231 /* Pack template extension, if appropriate. */
232 j = mappds->maplen;
233 if (mappds->needext && (mappds->extlen > 0))
234 {
235 for (i = 0; i < mappds->extlen; i++)
236 {
237 nbits = abs(mappds->ext[i]) * 8;
238 if (mappds->ext[i] >= 0 || ipdstmpl[j] >= 0)
239 sbit(cgrib, ipdstmpl + j, iofst, nbits);
240 else
241 {
242 sbit(cgrib, &one, iofst, 1);
243 temp = abs(ipdstmpl[j]);
244 sbit(cgrib, &temp, iofst + 1, nbits - 1);
245 }
246 iofst = iofst + nbits;
247 j++;
248 }
249 }
250 if (mappds->