NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
g2_unpack4.c
Go to the documentation of this file.
1
6#include "grib2_int.h"
7#include <stdio.h>
8#include <stdlib.h>
9
45g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl,
46 g2int *mappdslen, float **coordlist, g2int *numcoord)
47{
48
49 g2int needext, i, j, nbits, isecnum;
50 g2int lensec, isign, newlen;
51 g2int *coordieee;
52 g2int *lipdstmpl = 0;
53 float *lcoordlist;
54 gtemplate *mappds;
55
56 *ipdstmpl = NULL;
57 *coordlist = NULL;
58
59 gbit(cgrib, &lensec, *iofst, 32); /* Get Length of Section */
60 *iofst = *iofst + 32;
61 gbit(cgrib, &isecnum, *iofst, 8); /* Get Section Number */
62 *iofst = *iofst + 8;
63
64 if (isecnum != 4)
65 {
66 *numcoord = 0;
67 *mappdslen = 0;
68 return G2_UNPACK_BAD_SEC;
69 }
70
71 gbit(cgrib, numcoord, *iofst, 16); /* Get num of coordinate values */
72 *iofst = *iofst + 16;
73 gbit(cgrib, ipdsnum, *iofst, 16); /* Get Prod. Def Template num. */
74 *iofst = *iofst + 16;
75
76 /* Get Product Definition Template */
77 if (!(mappds = getpdstemplate(*ipdsnum)))
78 {
79 *mappdslen = 0;
80 return G2_UNPACK4_BAD_PDT;
81 }
82 *mappdslen = mappds->maplen;
83 needext = mappds->needext;
84
85 /* Unpack each value into array ipdstmpl from the the
86 * appropriate number of octets, which are specified in
87 * corresponding entries in array mappds. */
88 if (*mappdslen > 0)
89 lipdstmpl = calloc(*mappdslen, sizeof(g2int));
90 if (!lipdstmpl)
91 {
92 *mappdslen = 0;
93 *ipdstmpl = NULL;
94 if (mappds)
95 free(mappds);
96 return G2_UNPACK_NO_MEM;
97 }
98 *ipdstmpl = lipdstmpl;
99
100 for (i = 0; i < mappds->maplen; i++)
101 {
102 nbits = abs(mappds->map[i]) * 8;
103 if (mappds->map[i] >= 0)
104 {
105 gbit(cgrib, lipdstmpl + i, *iofst, nbits);
106 }
107 else
108 {
109 gbit(cgrib, &isign, *iofst, 1);
110 gbit(cgrib, lipdstmpl + i, *iofst + 1, nbits - 1);
111 if (isign == 1)
112 lipdstmpl[i] = -1 * lipdstmpl[i];
113 }
114 *iofst = *iofst + nbits;
115 }
116
117 /* Check to see if the Product Definition Template needs to be
118 * extended. The number of values in a specific template may
119 * vary depending on data specified in the "static" part of the
120 * gtemplate. */
121 if (needext == 1)
122 {
123 free(mappds);
124 mappds = extpdstemplate(*ipdsnum, lipdstmpl);
125 newlen = mappds->maplen + mappds->extlen;
126 lipdstmpl = realloc(lipdstmpl, newlen * sizeof(g2int));
127 *ipdstmpl = lipdstmpl;
128 /* Unpack the rest of the Product Definition Template */
129 j = 0;
130 for (i = *mappdslen; i < newlen; i++)
131 {
132 nbits = abs(mappds->ext[j]) * 8;
133 if (mappds->ext[j] >= 0)
134 {
135 gbit(cgrib, lipdstmpl + i, *iofst, nbits);
136 }
137 else
138 {
139 gbit(cgrib, &isign, *iofst, 1);
140 gbit(cgrib, lipdstmpl + i, *iofst + 1, nbits - 1);
141 if (isign == 1)
142 lipdstmpl[i] = -1 * lipdstmpl[i];
143 }
144 *iofst = *iofst + nbits;
145 j++;
146 }
147 *mappdslen = newlen;
148 }
149 if (mappds->ext)
150 free(mappds->ext);
151 if (mappds)
152 free(mappds);
153
154 /* Get Optional list of vertical coordinate values after the
155 * Product Definition Template, if necessary. */
156 *coordlist = NULL;
157 if (*numcoord != 0)
158 {
159 coordieee = calloc(*numcoord, sizeof(g2int));
160 lcoordlist = calloc(*numcoord, sizeof(float));
161 if (coordieee == 0 || lcoordlist == 0)
162 {
163 *numcoord = 0;
164 *coordlist = NULL;
165 if (coordieee)
166 free(coordieee);
167 if (lcoordlist)
168 free(lcoordlist);
169 return G2_UNPACK_NO_MEM;
170 }
171 else
172 {
173 *coordlist = lcoordlist;
174 }
175 gbits(cgrib, coordieee, *iofst, 32, 0, *numcoord);
176 rdieee(coordieee, *coordlist, *numcoord);
177 free(coordieee);
178 *iofst = *iofst + (32 * (*numcoord));
179 }
180
181 return G2_NO_ERROR;
182}
g2int g2_unpack4(unsigned char *cgrib, g2int *iofst, g2int *ipdsnum, g2int **ipdstmpl, g2int *mappdslen, float **coordlist, g2int *numcoord)
Unpack Section 4 (Product Definition Section) of a GRIB2 message.
Definition g2_unpack4.c:45
void gbit(unsigned char *in, g2int *iout, g2int iskip, g2int nbits)
Get arbitrary size values from a packed bit string, right justifying each value in the unpacked iout ...
Definition gbits.c:20
void gbits(unsigned char *in, g2int *iout, g2int iskip, g2int nbits, g2int nskip, g2int n)
Unpack arbitrary size values from a packed bit string, right justifying each value in the unpacked io...
Definition gbits.c:57
#define G2_UNPACK_BAD_SEC
Bad section number in unpacking function.
Definition grib2.h:449
#define G2_UNPACK4_BAD_PDT
In g2_unpack4(), undefined Product Definition Template.
Definition grib2.h:452
#define G2_UNPACK_NO_MEM
Error allocating memory in unpack function.
Definition grib2.h:450
#define G2_NO_ERROR
Function succeeded.
Definition grib2.h:423
int64_t g2int
Long integer type.
Definition grib2.h:32
Header file with internal function prototypes NCEPLIBS-g2c library.
g2int * ext
Number of octets of each entry in the extension part of the template.
Definition grib2_int.h:302
g2int extlen
Number of entries in the template extension.
Definition grib2_int.h:298
g2int * map
Number of octets of each entry in the static part of the template.
Definition grib2_int.h:292
g2int needext
Indicates whether or not the template needs to be extended.
Definition grib2_int.h:295
gtemplate * extpdstemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Product Definition Template,...
gtemplate * getpdstemplate(g2int number)
This subroutine returns PDS template information for a specified Product Definition Template.
g2int maplen
Number of entries in the static part of the template.
Definition grib2_int.h:288
void rdieee(g2int *rieee, float *a, g2int num)
Read a list of real values in 32-bit IEEE floating point format.
Definition rdieee.c:20
Struct for GRIB template, returned by getgridtemplate().
Definition grib2_int.h:278