NCEPLIBS-g2c 1.9.0
Loading...
Searching...
No Matches
comunpack.c
Go to the documentation of this file.
1
6#include <stdio.h>
7#include <stdlib.h>
8#include "grib2_int.h"
9
40int
41comunpack(unsigned char *cpack, g2int lensec, g2int idrsnum,
42 g2int *idrstmpl, g2int ndpts, float *fld)
43{
44 g2int nbitsd=0, isign;
45 g2int j, iofst, ival1, ival2, minsd, itemp, l, k, n, non=0;
46 g2int *ifld, *ifldmiss=0;
47 g2int *gref, *gwidth, *glen;
48 g2int itype, ngroups, nbitsgref, nbitsgwidth, nbitsglen;
49 g2int msng1, msng2;
50 float ref, bscale, dscale, rmiss1, rmiss2;
51 g2int totBit, totLen;
52
53 LOG((3, "comunpack lensec %ld idrsnum %ld ndpts %ld", lensec, idrsnum, ndpts));
54
55 rdieee(idrstmpl, &ref, 1);
56 bscale = (float)int_power(2.0, idrstmpl[1]);
57 dscale = (float)int_power(10.0, -idrstmpl[2]);
58 nbitsgref = idrstmpl[3];
59 itype = idrstmpl[4];
60 ngroups = idrstmpl[9];
61 nbitsgwidth = idrstmpl[11];
62 nbitsglen = idrstmpl[15];
63 if (idrsnum == 3)
64 nbitsd=idrstmpl[17] * 8;
65
66 /* Constant field */
67 if (ngroups == 0)
68 {
69 for (j = 0; j < ndpts; j++)
70 fld[j] = ref;
71 return(0);
72 }
73
74 iofst = 0;
75 ifld = (g2int *)calloc(ndpts, sizeof(g2int));
76 gref = (g2int *)calloc(ngroups, sizeof(g2int));
77 gwidth = (g2int *)calloc(ngroups, sizeof(g2int));
78
79 /* Get missing values, if supplied */
80 if (idrstmpl[6] == 1)
81 {
82 if (itype == 0)
83 rdieee(idrstmpl+7,&rmiss1,1);
84 else
85 rmiss1 = (float)idrstmpl[7];
86 }
87 if (idrstmpl[6] == 2)
88 {
89 if (itype == 0)
90 {
91 rdieee(idrstmpl+7,&rmiss1,1);
92 rdieee(idrstmpl+8,&rmiss2,1);
93 }
94 else {
95 rmiss1 = (float)idrstmpl[7];
96 rmiss2 = (float)idrstmpl[8];
97 }
98 }
99
100 /* Extract Spatial differencing values, if using DRS Template 5.3 */
101 if (idrsnum == 3)
102 {
103 if (nbitsd != 0)
104 {
105 /* wne mistake here shoujld be unsigned int */
106 gbit(cpack, &ival1, iofst, nbitsd);
107 iofst = iofst + nbitsd;
108 if (idrstmpl[16] == 2)
109 {
110 /* wne mistake here shoujld be unsigned int */
111 gbit(cpack, &ival2, iofst, nbitsd);
112 iofst = iofst + nbitsd;
113 }
114 gbit(cpack, &isign, iofst, 1);
115 iofst = iofst + 1;
116 gbit(cpack, &minsd, iofst, nbitsd - 1);
117 iofst = iofst + nbitsd - 1;
118 if (isign == 1)
119 minsd = -minsd;
120 }
121 else {
122 ival1 = 0;
123 ival2 = 0;
124 minsd = 0;
125 }
126 }
127
128 /* Extract Each Group's reference value */
129 if (nbitsgref != 0)
130 {
131 gbits(cpack, gref, iofst, nbitsgref, 0, ngroups);
132 itemp = nbitsgref * ngroups;
133 iofst = iofst + itemp;
134 if (itemp % 8 != 0)
135 iofst = iofst + (8 - (itemp % 8));
136 }
137 else
138 {
139 for (j = 0; j < ngroups; j++)
140 gref[j] = 0;
141 }
142
143 /* Extract Each Group's bit width */
144 if (nbitsgwidth != 0) {
145 gbits(cpack, gwidth, iofst, nbitsgwidth, 0, ngroups);
146 itemp = nbitsgwidth * ngroups;
147 iofst = iofst + itemp;
148 if (itemp % 8 != 0)
149 iofst = iofst + (8 - (itemp % 8));
150 }
151 else {
152 for (j = 0; j < ngroups; j++)
153 gwidth[j] = 0;
154 }
155
156 for (j = 0; j < ngroups; j++)
157 gwidth[j] = gwidth[j] + idrstmpl[10];
158
159 /* Extract Each Group's length (number of values in each group) */
160 glen = calloc(ngroups, sizeof(g2int));
161 if (nbitsglen != 0)
162 {
163 gbits(cpack, glen, iofst, nbitsglen, 0, ngroups);
164 itemp = nbitsglen * ngroups;
165 iofst = iofst + itemp;
166 if (itemp % 8 != 0)
167 iofst = iofst + (8 - (itemp % 8));
168 }
169 else
170 {
171 for (j = 0; j < ngroups; j++)
172 glen[j] = 0;
173 }
174 for (j = 0;j<ngroups;j++)
175 glen[j] = (glen[j]*idrstmpl[13])+idrstmpl[12];
176 glen[ngroups-1] = idrstmpl[14];
177
178 /* Test to see if the group widths and lengths are consistent
179 * with number of values, and length of section 7. */
180 totBit = 0;
181 totLen = 0;
182 for (j = 0; j < ngroups; j++)
183 {
184 totBit += (gwidth[j] * glen[j]);
185 totLen += glen[j];
186 }
187 if (totLen != ndpts)
188 return 1;
189 if (totBit / 8. > lensec)
190 return 1;
191
192 /* For each group, unpack data values */
193 if (idrstmpl[6] == 0)
194 { /* no missing values */
195 n = 0;
196 for (j = 0; j < ngroups; j++)
197 {
198 if (gwidth[j] != 0)
199 {
200 gbits(cpack, ifld + n, iofst, gwidth[j], 0, glen[j]);
201 for (k = 0; k < glen[j]; k++)
202 {
203 ifld[n] = ifld[n] + gref[j];
204 n = n + 1;
205 }
206 }
207 else
208 {
209 for (l = n; l < n + glen[j]; l++)
210 ifld[l] = gref[j];
211 n = n + glen[j];
212 }
213 iofst = iofst + (gwidth[j] * glen[j]);
214 }
215 }
216 else if (idrstmpl[6] == 1 || idrstmpl[6] == 2)
217 {
218 /* missing values included */
219 ifldmiss = malloc(ndpts * sizeof(g2int));
220 for (j = 0; j < ndpts; j++)
221 ifldmiss[j] = 0;
222 n = 0;
223 non = 0;
224 for (j = 0; j < ngroups; j++)
225 {
226 if (gwidth[j] != 0)
227 {
228 msng1 = (g2int)int_power(2.0, gwidth[j]) - 1;
229 msng2 = msng1 - 1;
230 gbits(cpack, ifld + n, iofst, gwidth[j], 0, glen[j]);
231 iofst = iofst + (gwidth[j] * glen[j]);
232 for (k = 0; k < glen[j]; k++)
233 {
234 if (ifld[n] == msng1)
235 ifldmiss[n] = 1;
236 else if (idrstmpl[6] == 2 && ifld[n] == msng2)
237 ifldmiss[n] = 2;
238 else {
239 ifldmiss[n] = 0;
240 ifld[non++] = ifld[n] + gref[j];
241 }
242 n++;
243 }
244 }
245 else
246 {
247 msng1 = (g2int)int_power(2.0, nbitsgref) -1;
248 msng2 = msng1 - 1;
249 if (gref[j] == msng1)
250 {
251 for (l = n; l < n + glen[j]; l++)
252 ifldmiss[l] = 1;
253 }
254 else if (idrstmpl[6] == 2 && gref[j] == msng2)
255 {
256 for (l = n; l < n + glen[j]; l++)
257 ifldmiss[l] = 2;
258 }
259 else
260 {
261 for (l = n; l < n + glen[j]; l++)
262 ifldmiss[l] = 0;
263 for (l = non; l < non + glen[j]; l++)
264 ifld[l] = gref[j];
265 non += glen[j];
266 }
267 n = n + glen[j];
268 }
269 }
270 }
271
272 if (gref)
273 free(gref);
274 if (gwidth)
275 free(gwidth);
276 if (glen)
277 free(glen);
278
279 /* If using spatial differences, add overall min value, and sum up recursively */
280 if (idrsnum == 3)
281 { /* spatial differencing */
282 if (idrstmpl[16] == 1)
283 { /* first order */
284 ifld[0] = ival1;
285 if (idrstmpl[6] == 0)
286 itemp = ndpts; /* no missing values */
287 else
288 itemp = non;
289 for (n = 1; n < itemp; n++)
290 {
291 ifld[n] = ifld[n] + minsd;
292 ifld[n] = ifld[n] + ifld[n - 1];
293 }
294 }
295 else if (idrstmpl[16] == 2)
296 { /* second order */
297 ifld[0] = ival1;
298 ifld[1] = ival2;
299 if (idrstmpl[6] == 0)
300 itemp = ndpts; /* no missing values */
301 else
302 itemp = non;
303 for (n = 2; n < itemp; n++)
304 {
305 ifld[n] = ifld[n] + minsd;
306 ifld[n] = ifld[n] + (2 * ifld[n - 1]) - ifld[n - 2];
307 }
308 }
309 }
310
311 /* Scale data back to original form */
312 if (idrstmpl[6] == 0)
313 { /* no missing values */
314 for (n = 0; n <ndpts; n++)
315 {
316 fld[n] = (((float)ifld[n] * bscale) + ref) * dscale;
317 }
318 }
319 else if (idrstmpl[6] == 1 || idrstmpl[6] == 2)
320 {
321 /* missing values included */
322 non = 0;
323 for (n = 0; n < ndpts; n++)
324 {
325 if (ifldmiss[n] == 0)
326 {
327 fld[n] = (((float)ifld[non++] * bscale) + ref) * dscale;
328 }
329 else if (ifldmiss[n] == 1)
330 fld[n] = rmiss1;
331 else if (ifldmiss[n] == 2)
332 fld[n] = rmiss2;
333 }
334 if (ifldmiss)
335 free(ifldmiss);
336 }
337
338 if (ifld)
339 free(ifld);
340
341 return 0;
342}
int comunpack(unsigned char *cpack, g2int lensec, g2int idrsnum, g2int *idrstmpl, g2int ndpts, float *fld)
Unpack a data field that was packed using a complex packing algorithm, using info from the GRIB2 Data...
Definition comunpack.c:41
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 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
int64_t g2int
Long integer type.
Definition grib2.h:32
Header file with internal function prototypes NCEPLIBS-g2c library.
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition int_power.c:18
#define LOG(e)
Ignore logging to stdout.
Definition grib2_int.h:426
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