NCEPLIBS-g2c  1.8.0
g2_unpack3.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "grib2_int.h"
9 
61 g2int
62 g2_unpack3(unsigned char *cgrib, g2int *iofst, g2int **igds, g2int **igdstmpl,
63  g2int *mapgridlen, g2int **ideflist, g2int *idefnum)
64 {
65  g2int i, j, nbits, isecnum;
66  g2int lensec, ibyttem = 0, isign, newlen;
67  g2int *ligds, *ligdstmpl = NULL, *lideflist = NULL;
68  gtemplate *mapgrid;
69 
70  *igds = NULL;
71  *igdstmpl = NULL;
72  *ideflist = NULL;
73 
74  gbit(cgrib, &lensec, *iofst, 32); /* Get Length of Section */
75  *iofst = *iofst + 32;
76  gbit(cgrib, &isecnum, *iofst, 8); /* Get Section Number */
77  *iofst = *iofst + 8;
78 
79  if (isecnum != 3)
80  {
81  *idefnum = 0;
82  *mapgridlen = 0;
83  return G2_UNPACK_BAD_SEC;
84  }
85 
86  ligds = calloc(5, sizeof(g2int));
87  *igds = ligds;
88 
89  gbit(cgrib, &ligds[0], *iofst, 8); /* Get source of Grid def. */
90  *iofst = *iofst + 8;
91  gbit(cgrib, &ligds[1], *iofst, 32); /* Get number of grid pts. */
92  *iofst = *iofst + 32;
93  gbit(cgrib, &ligds[2], *iofst, 8); /* Get num octets for opt. list */
94  *iofst = *iofst + 8;
95  gbit(cgrib, &ligds[3], *iofst, 8); /* Get interpret. for opt. list */
96  *iofst = *iofst + 8;
97  gbit(cgrib, &ligds[4], *iofst, 16); /* Get Grid Def Template num. */
98  *iofst = *iofst + 16;
99 
100  if (ligds[4] != 65535)
101  {
102  /* Get Grid Definition Template */
103  if (!(mapgrid = getgridtemplate(ligds[4])))
104  { /* undefined template */
105  free(ligds);
106  return G2_UNPACK3_BAD_GDT;
107  }
108  *mapgridlen = mapgrid->maplen;
109 
110  /* Unpack each value into array igdstmpl from the the
111  * appropriate number of octets, which are specified in
112  * corresponding entries in array mapgrid. */
113  if (*mapgridlen > 0)
114  {
115  if (!(ligdstmpl = calloc(*mapgridlen, sizeof(g2int))))
116  {
117  *mapgridlen = 0;
118  *igdstmpl = NULL;
119  if (mapgrid)
120  free(mapgrid);
121  return G2_UNPACK_NO_MEM;
122  }
123  *igdstmpl = ligdstmpl;
124  }
125  ibyttem = 0;
126  for (i = 0; i < *mapgridlen; i++)
127  {
128  nbits = abs(mapgrid->map[i]) * 8;
129  if (mapgrid->map[i] >= 0)
130  {
131  gbit(cgrib, ligdstmpl + i, *iofst, nbits);
132  }
133  else
134  {
135  gbit(cgrib, &isign, *iofst, 1);
136  gbit(cgrib, ligdstmpl + i, *iofst + 1, nbits - 1);
137  if (isign == 1)
138  ligdstmpl[i] = -1 * ligdstmpl[i];
139  }
140  *iofst = *iofst + nbits;
141  ibyttem = ibyttem + abs(mapgrid->map[i]);
142  }
143 
144  /* Check to see if the Grid Definition Template needs to be
145  * extended. The number of values in a specific template may
146  * vary depending on data specified in the "static" part of
147  * the gtemplate. */
148  if (mapgrid->needext == 1)
149  {
150  free(mapgrid);
151  mapgrid = extgridtemplate(ligds[4], ligdstmpl);
152  /* Unpack the rest of the Grid Definition Template */
153  newlen = mapgrid->maplen + mapgrid->extlen;
154  ligdstmpl = realloc(ligdstmpl, newlen * sizeof(g2int));
155  *igdstmpl = ligdstmpl;
156  j = 0;
157  for (i = *mapgridlen; i < newlen; i++)
158  {
159  nbits = abs(mapgrid->ext[j]) * 8;
160  if (mapgrid->ext[j] >= 0)
161  {
162  gbit(cgrib, ligdstmpl + i, *iofst, nbits);
163  }
164  else
165  {
166  gbit(cgrib, &isign, *iofst, 1);
167  gbit(cgrib, ligdstmpl + i, *iofst + 1, nbits - 1);
168  if (isign == 1)
169  ligdstmpl[i] = -1 * ligdstmpl[i];
170  }
171  *iofst = *iofst + nbits;
172  ibyttem = ibyttem + abs(mapgrid->ext[j]);
173  j++;
174  }
175  *mapgridlen = newlen;
176  }
177  if (mapgrid->ext)
178  free(mapgrid->ext);
179  if (mapgrid)
180  free(mapgrid);
181  }
182  else
183  { /* No Grid Definition Template */
184  *mapgridlen = 0;
185  *igdstmpl = 0;
186  }
187 
188  /* Unpack optional list of numbers defining number of points in
189  * each row or column, if included. This is used for non
190  * regular grids. */
191  if (ligds[2] != 0)
192  {
193  nbits = ligds[2] * 8;
194  *idefnum = (lensec - 14 - ibyttem) / ligds[2];
195  if (*idefnum > 0)
196  lideflist = calloc(*idefnum, sizeof(g2int));
197  if (!lideflist)
198  {
199  *idefnum = 0;
200  *ideflist = NULL;
201  return G2_UNPACK_NO_MEM;
202  }
203  *ideflist = lideflist;
204  gbits(cgrib, lideflist, *iofst, nbits, 0, *idefnum);
205  *iofst = *iofst + (nbits * *idefnum);
206  }
207  else
208  {
209  *idefnum = 0;
210  *ideflist = NULL;
211  }
212 
213  return G2_NO_ERROR; /* End of Section 3 processing */
214 }
g2int g2_unpack3(unsigned char *cgrib, g2int *iofst, g2int **igds, g2int **igdstmpl, g2int *mapgridlen, g2int **ideflist, g2int *idefnum)
This routine unpacks Section 3 (Grid Definition Section) from a GRIB2 message.
Definition: g2_unpack3.c:62
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_UNPACK_NO_MEM
Error allocating memory in unpack function.
Definition: grib2.h:465
#define G2_NO_ERROR
Function succeeded.
Definition: grib2.h:438
#define G2_UNPACK3_BAD_GDT
In g2_unpack3(), undefined Grid Definition Template.
Definition: grib2.h:466
int64_t g2int
Long integer type.
Definition: grib2.h:33
Header file with internal function prototypes NCEPLIBS-g2c library.
gtemplate * extgridtemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Grid Definition Template,...
g2int * ext
Number of octets of each entry in the extension part of the template.
Definition: grib2_int.h:300
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
g2int maplen
Number of entries in the static part of the template.
Definition: grib2_int.h:286
gtemplate * getgridtemplate(g2int number)
This subroutine returns grid template information for a specified Grid Definition Template for [Secti...
Struct for GRIB template, returned by getgridtemplate().
Definition: grib2_int.h:276