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