NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
comunpack.c
Go to the documentation of this file.
1
6#include "grib2_int.h"
7#include <stdio.h>
8#include <stdlib.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 {
96 rmiss1 = (float)idrstmpl[7];
97 rmiss2 = (float)idrstmpl[8];
98 }
99 }
100
101 /* Extract Spatial differencing values, if using DRS Template 5.3 */
102 if (idrsnum == 3)
103 {
104 if (nbitsd != 0)
105 {
106 /* wne mistake here shoujld be unsigned int */
107 gbit(cpack, &ival1, iofst, nbitsd);
108 iofst = iofst + nbitsd;
109 if (idrstmpl[16] == 2)
110 {
111 /* wne mistake here shoujld be unsigned int */
112 gbit(cpack, &ival2, iofst, nbitsd);
113 iofst = iofst + nbitsd;
114 }
115 gbit(cpack, &isign, iofst, 1);
116 iofst = iofst + 1;
117 gbit(cpack, &minsd, iofst, nbitsd - 1);
118 iofst = iofst + nbitsd - 1;
119 if (isign == 1)
120 minsd = -minsd;
121 }
122 else
123 {
124 ival1 = 0;
125 ival2 = 0;
126 minsd = 0;
127 }
128 }
129
130 /* Extract Each Group's reference value */
131 if (nbitsgref != 0)
132 {
133 gbits(cpack, gref, iofst, nbitsgref, 0, ngroups);
134 itemp = nbitsgref * ngroups;
135 iofst = iofst + itemp;
136 if (itemp % 8 != 0)
137 iofst = iofst + (8 - (itemp % 8));
138 }
139 else
140 {
141 for (j = 0; j < ngroups; j++)
142 gref[j] = 0;
143 }
144
145 /* Extract Each Group's bit width */
146 if (nbitsgwidth != 0)
147 {
148 gbits(cpack, gwidth, iofst, nbitsgwidth, 0, ngroups);
149 itemp = nbitsgwidth * ngroups;
150 iofst = iofst + itemp;
151 if (itemp % 8 != 0)
152 iofst = iofst + (8 - (itemp % 8));
153 }
154 else
155 {
156 for (j = 0; j < ngroups; j++)
157 gwidth[j] = 0;
158 }
159
160 for (j = 0; j < ngroups; j++)
161 gwidth[j] = gwidth[j] + idrstmpl[10];
162
163 /* Extract Each Group's length (number of values in each group) */
164 glen = calloc(ngroups, sizeof(g2int));
165 if (nbitsglen != 0)
166 {
167 gbits(cpack, glen, iofst, nbitsglen, 0, ngroups);
168 itemp = nbitsglen * ngroups;
169 iofst = iofst + itemp;
170 if (itemp % 8 != 0)
171 iofst = iofst + (8 - (itemp % 8));
172 }
173 else
174 {
175 for (j = 0; j < ngroups; j++)
176 glen[j] = 0;
177 }
178 for (j = 0; j < ngroups; j++)
179 glen[j] = (glen[j] * idrstmpl[13]) + idrstmpl[12];
180 glen[ngroups - 1] = idrstmpl[14];
181
182 /* Test to see if the group widths and lengths are consistent
183 * with number of values, and length of section 7. */
184 totBit = 0;
185 totLen = 0;
186 for (j = 0; j < ngroups; j++)
187 {
188 totBit += (gwidth[j] * glen[j]);
189 totLen += glen[j];
190 }
191 if (totLen != ndpts)
192 return 1;
193 if (totBit / 8. > lensec)
194 return 1;
195
196 /* For each group, unpack data values */
197 if (idrstmpl[6] == 0)
198 { /* no missing values */
199 n = 0;
200 for (j = 0; j < ngroups; j++)
201 {
202 if (gwidth[j] != 0)
203 {
204 gbits(cpack, ifld + n, iofst, gwidth[j], 0, glen[j]);
205 for (k = 0; k < glen[j]; k++)
206 {
207 ifld[n] = ifld[n] + gref[j];
208 n = n + 1;
209 }
210 }
211 else
212 {
213 for (l = n; l < n + glen[j]; l++)
214 ifld[l] = gref[j];
215 n = n + glen[j];
216 }
217 iofst = iofst + (gwidth[j] * glen[j]);
218 }
219 }
220 else if (idrstmpl[6] == 1 || idrstmpl[6] == 2)
221 {
222 /* missing values included */
223 ifldmiss = malloc(ndpts * sizeof(g2int));
224 for (j = 0; j < ndpts; j++)
225 ifldmiss[j] = 0;
226 n = 0;
227 non = 0;
228 for (j = 0; j < ngroups; j++)
229 {
230 if (gwidth[j] != 0)
231 {
232 msng1 = (g2int)int_power(2.0, gwidth[j]) - 1;
233 msng2 = msng1 - 1;
234 gbits(cpack, ifld + n, iofst, gwidth[j], 0, glen[j]);
235 iofst = iofst + (gwidth[j] * glen[j]);
236 for (k = 0; k < glen[j]; k++)
237 {
238 if (ifld[n] == msng1)
239 ifldmiss[n] = 1;
240 else if (idrstmpl[6] == 2 && ifld[n] == msng2)
241 ifldmiss[n] = 2;
242 else
243 {
244 ifldmiss[n] = 0;
245 ifld[non++] = ifld[n] + gref[j];
246 }
247 n++;
248 }
249 }
250 else
251 {
252 msng1 = (g2int)int_power(2.0, nbitsgref) - 1;
253 msng2 = msng1 - 1;
254 if (gref[j] == msng1)
255 {
256 for (l = n; l < n + glen[j]; l++)
257 ifldmiss[l] = 1;
258 }
259 else if (idrstmpl[6] == 2 && gref[j] == msng2)
260 {
261 for (l = n; l < n + glen[j]; l++)
262 ifldmiss[l] = 2;
263 }
264 else
265 {
266 for (l = n; l < n + glen[j]; l++)
267 ifldmiss[l] = 0;
268 for (l = non; l < non + glen[j]; l++)
269 ifld[l] = gref[j];
270 non += glen[j];
271 }
272 n = n + glen[j];
273 }
274 }
275 }
276
277 if (gref)
278 free(gref);
279 if (gwidth)
280 free(gwidth);
281 if (glen)
282 free(glen);
283
284 /* If using spatial differences, add overall min value, and sum up recursively */
285 if (idrsnum == 3)
286 { /* spatial differencing */
287 if (idrstmpl[16] == 1)
288 { /* first order */
289 ifld[0] = ival1;
290 if (idrstmpl[6] == 0)
291 itemp = ndpts; /* no missing values */
292 else
293 itemp = non;
294 for (n = 1; n < itemp; n++)
295 {
296 ifld[n] = ifld[n] + minsd;
297 ifld[n] = ifld[n] + ifld[n - 1];
298 }
299 }
300 else if (idrstmpl[16] == 2)
301 { /* second order */
302 ifld[0] = ival1;
303 ifld[1] = ival2;
304 if (idrstmpl[6] == 0)
305 itemp = ndpts; /* no missing values */
306 else
307 itemp = non;
308 for (n = 2; n < itemp; n++)
309 {
310 ifld[n] = ifld[n] + minsd;
311 ifld[n] = ifld[n] + (2 * ifld[n - 1]) - ifld[n - 2];
312 }
313 }
314 }
315
316 /* Scale data back to original form */
317 if (idrstmpl[6] == 0)
318 { /* no missing values */
319 for (n = 0; n < ndpts; n++)
320 {
321 fld[n] = (((float)ifld[n] * bscale) + ref) * dscale;
322 }
323 }
324 else if (idrstmpl[6] == 1 || idrstmpl[6] == 2)
325 {
326 /* missing values included */
327 non = 0;
328 for (n = 0; n < ndpts; n++)
329 {
330 if (ifldmiss[n] == 0)
331 {
332 fld[n] = (((float)ifld[non++] * bscale) + ref) * dscale;
333 }
334 else if (ifldmiss[n] == 1)
335 fld[n] = rmiss1;
336 else if (ifldmiss[n] == 2)
337 fld[n] = rmiss2;
338 }
339 if (ifldmiss)
340 free(ifldmiss);
341 }
342
343 if (ifld)
344 free(ifld);
345
346 return 0;
347}
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:428
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