NCEPLIBS-g2c  1.6.4
g2_unpack4.c
Go to the documentation of this file.
1 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "grib2.h"
10 
44 g2int
45 g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl,
46  g2int *mappdslen, g2float **coordlist, g2int *numcoord)
47 {
48 
49  g2int ierr, needext, i, j, nbits, isecnum;
50  g2int lensec, isign, newlen;
51  g2int *coordieee;
52  g2int *lipdstmpl = 0;
53  g2float *lcoordlist;
54  gtemplate *mappds;
55 
56  ierr = 0;
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  ierr = 2;
68  *numcoord = 0;
69  *mappdslen = 0;
70  /* fprintf(stderr, "g2_unpack4: Not Section 4 data.\n");*/
71  return(ierr);
72  }
73 
74  gbit(cgrib, numcoord, *iofst, 16); /* Get num of coordinate values */
75  *iofst = *iofst + 16;
76  gbit(cgrib, ipdsnum, *iofst, 16); /* Get Prod. Def Template num. */
77  *iofst = *iofst + 16;
78 
79  /* Get Product Definition Template */
80  mappds = getpdstemplate(*ipdsnum);
81  if (mappds == 0)
82  { /* undefine template */
83  ierr = 5;
84  *mappdslen = 0;
85  return(ierr);
86  }
87  *mappdslen = mappds->maplen;
88  needext = mappds->needext;
89 
90  /* Unpack each value into array ipdstmpl from the the
91  * appropriate number of octets, which are specified in
92  * corresponding entries in array mappds. */
93  if (*mappdslen > 0)
94  lipdstmpl = calloc(*mappdslen, sizeof(g2int));
95  if (lipdstmpl == 0)
96  {
97  ierr = 6;
98  *mappdslen = 0;
99  *ipdstmpl = NULL;
100  if (mappds)
101  free(mappds);
102  return(ierr);
103  }
104  *ipdstmpl = lipdstmpl;
105 
106  for (i = 0; i < mappds->maplen; i++)
107  {
108  nbits = abs(mappds->map[i]) * 8;
109  if (mappds->map[i] >= 0)
110  {
111  gbit(cgrib, lipdstmpl + i, *iofst, nbits);
112  }
113  else
114  {
115  gbit(cgrib, &isign, *iofst, 1);
116  gbit(cgrib, lipdstmpl + i, *iofst + 1, nbits - 1);
117  if (isign == 1) lipdstmpl[i] = -1 * lipdstmpl[i];
118  }
119  *iofst = *iofst + nbits;
120  }
121 
122  /* Check to see if the Product Definition Template needs to be
123  * extended. The number of values in a specific template may
124  * vary depending on data specified in the "static" part of the
125  * gtemplate. */
126  if (needext == 1)
127  {
128  free(mappds);
129  mappds = extpdstemplate(*ipdsnum, lipdstmpl);
130  newlen = mappds->maplen+mappds->extlen;
131  lipdstmpl = realloc(lipdstmpl, newlen * sizeof(g2int));
132  *ipdstmpl = lipdstmpl;
133  /* Unpack the rest of the Product Definition Template */
134  j = 0;
135  for (i = *mappdslen; i < newlen; i++)
136  {
137  nbits = abs(mappds->ext[j]) * 8;
138  if (mappds->ext[j] >= 0)
139  {
140  gbit(cgrib, lipdstmpl + i, *iofst, nbits);
141  }
142  else
143  {
144  gbit(cgrib, &isign, *iofst, 1);
145  gbit(cgrib, lipdstmpl + i, *iofst+1, nbits-1);
146  if (isign == 1)
147  lipdstmpl[i] = -1 * lipdstmpl[i];
148  }
149  *iofst = *iofst + nbits;
150  j++;
151  }
152  *mappdslen = newlen;
153  }
154  if (mappds->ext)
155  free(mappds->ext);
156  if (mappds)
157  free(mappds);
158 
159  /* Get Optional list of vertical coordinate values after the
160  * Product Definition Template, if necessary. */
161  *coordlist = 0; /* NULL */
162  if (*numcoord != 0)
163  {
164  coordieee = calloc(*numcoord, sizeof(g2int));
165  lcoordlist = calloc(*numcoord, sizeof(g2float));
166  if (coordieee == 0 || lcoordlist == 0)
167  {
168  ierr = 6;
169  *numcoord = 0;
170  *coordlist = 0; /* NULL */
171  if (coordieee)
172  free(coordieee);
173  if (lcoordlist)
174  free(lcoordlist);
175  return(ierr);
176  }
177  else
178  {
179  *coordlist = lcoordlist;
180  }
181  gbits(cgrib, coordieee, *iofst, 32, 0, *numcoord);
182  rdieee(coordieee, *coordlist, *numcoord);
183  free(coordieee);
184  *iofst = *iofst + (32 * (*numcoord));
185  }
186 
187  return(ierr); /* End of Section 4 processing */
188 
189 }
g2int g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl, g2int *mappdslen, g2float **coordlist, g2int *numcoord)
This subroutine unpacks Section 4 (Product Definition Section) as defined in GRIB Edition 2.
Definition: g2_unpack4.c:45
void gbit(unsigned char *in, g2int *iout, g2int iskip, g2int nbyte)
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 nbyte, g2int nskip, g2int n)
Get bits - unpack bits: Extract arbitrary size values from a packed bit string, right justifying each...
Definition: gbits.c:57
Header file for NCEPLIBS-g2c library.
float g2float
Float type.
Definition: grib2.h:22
g2int * ext
Number of octets of each entry in the extension part of the template.
Definition: grib2.h:52
g2int extlen
Number of entries in the template extension.
Definition: grib2.h:48
g2int * map
Number of octets of each entry in the static part of the template.
Definition: grib2.h:42
g2int needext
Indicates whether or not the template needs to be extended.
Definition: grib2.h:45
g2int maplen
Number of entries in the static part of the template.
Definition: grib2.h:38
int64_t g2int
Long integer type.
Definition: grib2.h:20
Struct for GRIB template.
Definition: grib2.h:28
gtemplate * extpdstemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Product Definition Template,...
Definition: pdstemplates.c:121
gtemplate * getpdstemplate(g2int number)
This subroutine returns PDS template information for a specified Product Definition Template.
Definition: pdstemplates.c:73
void rdieee(g2int *rieee, g2float *a, g2int num)
This subroutine reads a list of real values in 32-bit IEEE floating point format.
Definition: rdieee.c:20