NCEPLIBS-g2c  1.8.0
g2_unpack4.c
Go to the documentation of this file.
1 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "grib2_int.h"
10 
45 g2int
46 g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl,
47  g2int *mappdslen, float **coordlist, g2int *numcoord)
48 {
49 
50  g2int needext, i, j, nbits, isecnum;
51  g2int lensec, isign, newlen;
52  g2int *coordieee;
53  g2int *lipdstmpl = 0;
54  float *lcoordlist;
55  gtemplate *mappds;
56 
57  *ipdstmpl = NULL;
58  *coordlist = NULL;
59 
60  gbit(cgrib, &lensec, *iofst, 32); /* Get Length of Section */
61  *iofst = *iofst + 32;
62  gbit(cgrib, &isecnum, *iofst, 8); /* Get Section Number */
63  *iofst = *iofst + 8;
64 
65  if (isecnum != 4)
66  {
67  *numcoord = 0;
68  *mappdslen = 0;
69  return G2_UNPACK_BAD_SEC;
70  }
71 
72  gbit(cgrib, numcoord, *iofst, 16); /* Get num of coordinate values */
73  *iofst = *iofst + 16;
74  gbit(cgrib, ipdsnum, *iofst, 16); /* Get Prod. Def Template num. */
75  *iofst = *iofst + 16;
76 
77  /* Get Product Definition Template */
78  if (!(mappds = getpdstemplate(*ipdsnum)))
79  {
80  *mappdslen = 0;
81  return G2_UNPACK4_BAD_PDT;
82  }
83  *mappdslen = mappds->maplen;
84  needext = mappds->needext;
85 
86  /* Unpack each value into array ipdstmpl from the the
87  * appropriate number of octets, which are specified in
88  * corresponding entries in array mappds. */
89  if (*mappdslen > 0)
90  lipdstmpl = calloc(*mappdslen, sizeof(g2int));
91  if (!lipdstmpl)
92  {
93  *mappdslen = 0;
94  *ipdstmpl = NULL;
95  if (mappds)
96  free(mappds);
97  return G2_UNPACK_NO_MEM;
98  }
99  *ipdstmpl = lipdstmpl;
100 
101  for (i = 0; i < mappds->maplen; i++)
102  {
103  nbits = abs(mappds->map[i]) * 8;
104  if (mappds->map[i] >= 0)
105  {
106  gbit(cgrib, lipdstmpl + i, *iofst, nbits);
107  }
108  else
109  {
110  gbit(cgrib, &isign, *iofst, 1);
111  gbit(cgrib, lipdstmpl + i, *iofst + 1, nbits - 1);
112  if (isign == 1) lipdstmpl[i] = -1 * lipdstmpl[i];
113  }
114  *iofst = *iofst + nbits;
115  }
116 
117  /* Check to see if the Product Definition Template needs to be
118  * extended. The number of values in a specific template may
119  * vary depending on data specified in the "static" part of the
120  * gtemplate. */
121  if (needext == 1)
122  {
123  free(mappds);
124  mappds = extpdstemplate(*ipdsnum, lipdstmpl);
125  newlen = mappds->maplen+mappds->extlen;
126  lipdstmpl = realloc(lipdstmpl, newlen * sizeof(g2int));
127  *ipdstmpl = lipdstmpl;
128  /* Unpack the rest of the Product Definition Template */
129  j = 0;
130  for (i = *mappdslen; i < newlen; i++)
131  {
132  nbits = abs(mappds->ext[j]) * 8;
133  if (mappds->ext[j] >= 0)
134  {
135  gbit(cgrib, lipdstmpl + i, *iofst, nbits);
136  }
137  else
138  {
139  gbit(cgrib, &isign, *iofst, 1);
140  gbit(cgrib, lipdstmpl + i, *iofst+1, nbits-1);
141  if (isign == 1)
142  lipdstmpl[i] = -1 * lipdstmpl[i];
143  }
144  *iofst = *iofst + nbits;
145  j++;
146  }
147  *mappdslen = newlen;
148  }
149  if (mappds->ext)
150  free(mappds->ext);
151  if (mappds)
152  free(mappds);
153 
154  /* Get Optional list of vertical coordinate values after the
155  * Product Definition Template, if necessary. */
156  *coordlist = NULL;
157  if (*numcoord != 0)
158  {
159  coordieee = calloc(*numcoord, sizeof(g2int));
160  lcoordlist = calloc(*numcoord, sizeof(float));
161  if (coordieee == 0 || lcoordlist == 0)
162  {
163  *numcoord = 0;
164  *coordlist = NULL;
165  if (coordieee)
166  free(coordieee);
167  if (lcoordlist)
168  free(lcoordlist);
169  return G2_UNPACK_NO_MEM;
170  }
171  else
172  {
173  *coordlist = lcoordlist;
174  }
175  gbits(cgrib, coordieee, *iofst, 32, 0, *numcoord);
176  rdieee(coordieee, *coordlist, *numcoord);
177  free(coordieee);
178  *iofst = *iofst + (32 * (*numcoord));
179  }
180 
181  return G2_NO_ERROR;
182 }
g2int g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl, g2int *mappdslen, float **coordlist, g2int *numcoord)
This subroutine unpacks Section 4 (Product Definition Section) as defined in GRIB Edition 2.
Definition: g2_unpack4.c:46
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
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
#define G2_UNPACK_BAD_SEC
Bad section number in unpacking function.
Definition: grib2.h:464
#define G2_UNPACK4_BAD_PDT
In g2_unpack4(), undefined Product Definition Template.
Definition: grib2.h:467
#define G2_UNPACK_NO_MEM
Error allocating memory in unpack function.
Definition: grib2.h:465
#define G2_NO_ERROR
Function succeeded.
Definition: grib2.h:438
int64_t g2int
Long integer type.
Definition: grib2.h:33
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:300
gtemplate * extpdstemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Product Definition Template,...
Definition: pdstemplates.c:325
g2int extlen
Number of entries in the template extension.
Definition: grib2_int.h:296
g2int * map
Number of octets of each entry in the static part of the template.
Definition: grib2_int.h:290
g2int needext
Indicates whether or not the template needs to be extended.
Definition: grib2_int.h:293
gtemplate * getpdstemplate(g2int number)
This subroutine returns PDS template information for a specified Product Definition Template.
Definition: pdstemplates.c:277
g2int maplen
Number of entries in the static part of the template.
Definition: grib2_int.h:286
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
Struct for GRIB template, returned by getgridtemplate().
Definition: grib2_int.h:276