NCEPLIBS-g2c  1.6.4
g2_unpack3.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "grib2.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 ierr, i, j, nbits, isecnum;
61  g2int lensec, ibyttem = 0, isign, newlen;
62  g2int *ligds, *ligdstmpl = NULL, *lideflist = NULL;
63  gtemplate *mapgrid;
64 
65  ierr = 0;
66  *igds = NULL;
67  *igdstmpl = NULL;
68  *ideflist = NULL;
69 
70  gbit(cgrib, &lensec, *iofst, 32); /* Get Length of Section */
71  *iofst = *iofst + 32;
72  gbit(cgrib, &isecnum, *iofst, 8); /* Get Section Number */
73  *iofst = *iofst + 8;
74 
75  if (isecnum != 3)
76  {
77  ierr = 2;
78  *idefnum = 0;
79  *mapgridlen = 0;
80  /* fprintf(stderr, "g2_unpack3: Not Section 3 data.\n"); */
81  return(ierr);
82  }
83 
84  ligds = calloc(5, sizeof(g2int));
85  *igds = ligds;
86 
87  gbit(cgrib, &ligds[0], *iofst, 8); /* Get source of Grid def. */
88  *iofst = *iofst + 8;
89  gbit(cgrib, &ligds[1], *iofst, 32); /* Get number of grid pts. */
90  *iofst = *iofst + 32;
91  gbit(cgrib, &ligds[2], *iofst, 8); /* Get num octets for opt. list */
92  *iofst = *iofst + 8;
93  gbit(cgrib, &ligds[3], *iofst, 8); /* Get interpret. for opt. list */
94  *iofst = *iofst + 8;
95  gbit(cgrib, &ligds[4], *iofst, 16); /* Get Grid Def Template num. */
96  *iofst = *iofst + 16;
97 
98  if (ligds[4] != 65535)
99  {
100  /* Get Grid Definition Template */
101  mapgrid = getgridtemplate(ligds[4]);
102  if (!mapgrid)
103  { /* undefined template */
104  ierr = 5;
105  return(ierr);
106  }
107  *mapgridlen = mapgrid->maplen;
108 
109  /* Unpack each value into array igdstmpl from the the
110  * appropriate number of octets, which are specified in
111  * corresponding entries in array mapgrid. */
112  if (*mapgridlen > 0)
113  {
114  if (!(ligdstmpl = calloc(*mapgridlen, sizeof(g2int))))
115  {
116  ierr = 6;
117  *mapgridlen = 0;
118  *igdstmpl = NULL;
119  if (mapgrid)
120  free(mapgrid);
121  return(ierr);
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  ierr = 6;
200  *idefnum = 0;
201  *ideflist = NULL;
202  return(ierr);
203  }
204  *ideflist = lideflist;
205  gbits(cgrib, lideflist, *iofst, nbits, 0, *idefnum);
206  *iofst = *iofst + (nbits * *idefnum);
207  }
208  else
209  {
210  *idefnum = 0;
211  *ideflist = NULL;
212  }
213 
214  return(ierr); /* End of Section 3 processing */
215 }
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
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.
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 * extgridtemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Grid Definition Template,...
gtemplate * getgridtemplate(g2int number)
This subroutine returns grid template information for a specified Grid Definition Template for [Secti...
Definition: gridtemplates.c:75