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