NCEPLIBS-g2c  1.8.0
g2_unpack7.c
Go to the documentation of this file.
1 
18 #include <memory.h>
19 #include <string.h>
20 #include "grib2_int.h"
21 
67 static g2int
68 g2c_unpack7_int(unsigned char *cgrib, g2int *iofst, g2int igdsnum, g2int *igdstmpl,
69  g2int idrsnum, g2int *idrstmpl, g2int ndpts, int v1, float **fld)
70 {
71  g2int isecnum;
72  g2int ipos, lensec;
73  float *lfld;
74 
75  assert(cgrib && iofst && idrstmpl && fld);
76 
77  LOG((2, "g2c_unpack7_int *iofst %ld igdsnum %ld idrsnum %ld ndpts %ld v1 %d",
78  *iofst, igdsnum, idrsnum, ndpts, v1));
79 
80  /* Get Length of Section */
81  gbit(cgrib, &lensec, *iofst, 32);
82  *iofst = *iofst + 32;
83  LOG((3, "lensec %ld", lensec));
84 
85  /* Get Section Number */
86  gbit(cgrib, &isecnum, *iofst, 8);
87  *iofst = *iofst + 8;
88 
89  if (isecnum != 7)
90  return G2_UNPACK_BAD_SEC;
91 
92  ipos = *iofst / 8;
93 
94  /* If we're using the V1 API, allocate memory for the unpacked
95  * data. If we are using the v2 API, the caller is responsible for
96  * allocating memory to hold the data. */
97  if (v1)
98  {
99  if (!(lfld = calloc(ndpts ? ndpts : 1, sizeof(float))))
100  return G2_UNPACK_NO_MEM;
101  *fld = lfld;
102  }
103  else
104  lfld = *fld;
105 
106  if (idrsnum == 0)
107  {
108  simunpack(cgrib + ipos, idrstmpl, ndpts, *fld);
109  }
110  else if (idrsnum == 2 || idrsnum == 3)
111  {
112  if (comunpack(cgrib+ipos, lensec, idrsnum, idrstmpl, ndpts, *fld))
113  return G2_UNPACK7_CORRUPT_SEC;
114  }
115  else if (idrsnum == 50)
116  {
117  /* Spectral Simple */
118  simunpack(cgrib + ipos, idrstmpl, ndpts - 1, lfld + 1);
119  rdieee(idrstmpl + 4, lfld, 1);
120  }
121  else if (idrsnum == 51)
122  {
123  /* Spectral complex */
124  if (igdsnum >= 50 && igdsnum <= 53)
125  specunpack(cgrib + ipos, idrstmpl, ndpts, igdstmpl[0], igdstmpl[2],
126  igdstmpl[2], lfld);
127  else
128  {
129  if (v1)
130  fprintf(stderr, "g2_unpack7: Cannot use GDT 3.%d to unpack Data Section 5.51.\n",
131  (int)igdsnum);
132  if (lfld)
133  free(lfld);
134  *fld = NULL;
135  return G2_UNPACK7_WRONG_GDT;
136  }
137  }
138 #if defined USE_JPEG2000 || defined USE_OPENJPEG
139  else if (idrsnum == 40 || idrsnum == 40000)
140  {
141  jpcunpack(cgrib + ipos, lensec - 5, idrstmpl, ndpts, *fld);
142  }
143 #endif /* USE_JPEG2000 */
144 #ifdef USE_PNG
145  else if (idrsnum == 41 || idrsnum == 40010)
146  {
147  pngunpack(cgrib + ipos, lensec - 5, idrstmpl, ndpts, *fld);
148  }
149 #endif /* USE_PNG */
150 #ifdef USE_AEC
151  else if (idrsnum == 42)
152  {
153  aecunpack(cgrib + ipos, lensec - 5, idrstmpl, ndpts, *fld);
154  }
155 #endif /* USE_AEC */
156  else
157  {
158  if (v1)
159  fprintf(stderr, "g2_unpack7: Data Representation Template 5.%d not yet "
160  "implemented.\n", (int)idrsnum);
161  if (lfld)
162  free(lfld);
163  *fld = NULL;
164  return G2_UNPACK7_BAD_DRT;
165  }
166 
167  *iofst = *iofst + (8 * lensec);
168 
169  return G2_NO_ERROR;
170 }
171 
213 g2int
214 g2_unpack7(unsigned char *cgrib, g2int *iofst, g2int igdsnum, g2int *igdstmpl,
215  g2int idrsnum, g2int *idrstmpl, g2int ndpts, float **fld)
216 {
217  return g2c_unpack7_int(cgrib, iofst, igdsnum, igdstmpl, idrsnum, idrstmpl,
218  ndpts, 1, fld);
219 }
220 
258 int
259 g2c_unpack7(unsigned char *cgrib, int igdsnum, int gds_tmpl_len, long long int *gdstmpl,
260  int idrsnum, int drs_tmpl_len, long long int *drstmpl, int ndpts, float *fld)
261 {
262  g2int iofst = 0;
263  g2int *igdstmpl = NULL, *idrstmpl;
264  int i;
265  int ret;
266 
267  LOG((1, "g2c_unpack7 igdsnum %d gds_tmpl_len %d idrsnum %d drs_tmpl_len %d ndpts %d",
268  igdsnum, gds_tmpl_len, idrsnum, drs_tmpl_len, ndpts));
269 
270  /* Check inputs. */
271  assert(cgrib && drstmpl && fld);
272  if (gds_tmpl_len && !gdstmpl)
273  return G2C_EINVAL;
274 
275  /* Allocate memory to hold the g2int versions of the DRS and GDS
276  * template arrays. */
277  if (gds_tmpl_len)
278  if (!(igdstmpl = malloc(gds_tmpl_len * sizeof(g2int))))
279  return G2C_ENOMEM;
280  if (!(idrstmpl = malloc(drs_tmpl_len * sizeof(g2int))))
281  return G2C_ENOMEM;
282 
283  /* Copy the templates. */
284  if (gds_tmpl_len)
285  for (i = 0; i < gds_tmpl_len; i++)
286  igdstmpl[i] = gdstmpl[i];
287  for (i = 0; i < drs_tmpl_len; i++)
288  idrstmpl[i] = drstmpl[i];
289 
290  /* Call the internal function that does the work. */
291  ret = g2c_unpack7_int(cgrib, &iofst, igdsnum, igdstmpl, idrsnum, idrstmpl,
292  ndpts, 0, &fld);
293 
294  /* Free the g2int versions of the templates. */
295  if (igdstmpl)
296  free(igdstmpl);
297  free(idrstmpl);
298 
299  return ret;
300 }
301 
302 
g2int aecunpack(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts, float *fld)
Unpack AEC compressed data into an array of floats, using info from the GRIB2 Data Representation Tem...
Definition: aecunpack.c:139
int comunpack(unsigned char *cpack, g2int lensec, g2int idrsnum, g2int *idrstmpl, g2int ndpts, float *fld)
This subroutine unpacks a data field that was packed using a complex packing algorithm as defined in ...
Definition: comunpack.c:42
static g2int g2c_unpack7_int(unsigned char *cgrib, g2int *iofst, g2int igdsnum, g2int *igdstmpl, g2int idrsnum, g2int *idrstmpl, g2int ndpts, int v1, float **fld)
This subroutine unpacks Section 7 (Data Section) of a GRIB2 message.
Definition: g2_unpack7.c:68
g2int g2_unpack7(unsigned char *cgrib, g2int *iofst, g2int igdsnum, g2int *igdstmpl, g2int idrsnum, g2int *idrstmpl, g2int ndpts, float **fld)
This subroutine unpacks Section 7 (Data Section) of a GRIB2 message.
Definition: g2_unpack7.c:214
int g2c_unpack7(unsigned char *cgrib, int igdsnum, int gds_tmpl_len, long long int *gdstmpl, int idrsnum, int drs_tmpl_len, long long int *drstmpl, int ndpts, float *fld)
This subroutine unpacks Section 7 (Data Section) of a GRIB2 message.
Definition: g2_unpack7.c:259
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
#define G2_UNPACK7_BAD_DRT
In g2_unpack7(), unrecognized Data Representation Template.
Definition: grib2.h:472
#define G2_UNPACK_BAD_SEC
Bad section number in unpacking function.
Definition: grib2.h:464
#define G2_UNPACK7_CORRUPT_SEC
In g2_unpack7(), corrupt section 7.
Definition: grib2.h:470
#define G2C_ENOMEM
Out of memory.
Definition: grib2.h:500
#define G2_UNPACK_NO_MEM
Error allocating memory in unpack function.
Definition: grib2.h:465
#define G2_UNPACK7_WRONG_GDT
In g2_unpack7(), need one of GDT 3.50 through 3.53 to decode DRT 5.51.
Definition: grib2.h:471
#define G2_NO_ERROR
Function succeeded.
Definition: grib2.h:438
#define G2C_EINVAL
Invalid input.
Definition: grib2.h:496
int64_t g2int
Long integer type.
Definition: grib2.h:33
Header file with internal function prototypes NCEPLIBS-g2c library.
g2int jpcunpack(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts, float *fld)
Unpack JPEG2000 compressed data into an array of floats, using info from the GRIB2 Data Representatio...
Definition: jpcunpack.c:124
g2int pngunpack(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts, float *fld)
This subroutine unpacks a data field that was packed into a PNG image format using info from the GRIB...
Definition: pngunpack.c:117
#define LOG(e)
Ignore logging to stdout.
Definition: grib2_int.h:426
g2int specunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, g2int JJ, g2int KK, g2int MM, float *fld)
This subroutine unpacks a spectral data field that was packed using the complex packing algorithm for...
Definition: specunpack.c:35
g2int simunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, float *fld)
This subroutine unpacks a data field that was packed using a simple packing algorithm as defined in t...
Definition: simunpack.c:26
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