NCEPLIBS-g2c 1.9.0
Loading...
Searching...
No Matches
g2_unpack4.c
Go to the documentation of this file.
1
6#include <stdio.h>
7#include <stdlib.h>
8#include "grib2_int.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) lipdstmpl[i] = -1 * lipdstmpl[i];
112 }
113 *iofst = *iofst + nbits;
114 }
115
116 /* Check to see if the Product Definition Template needs to be
117 * extended. The number of values in a specific template may
118 * vary depending on data specified in the "static" part of the
119 * gtemplate. */
120 if (needext == 1)
121 {
122 free(mappds);
123 mappds = extpdstemplate(*ipdsnum, lipdstmpl);
124 newlen = mappds->maplen+mappds->extlen;
125 lipdstmpl = realloc(lipdstmpl, newlen * sizeof(g2int));
126 *ipdstmpl = lipdstmpl;
127 /* Unpack the rest of the Product Definition Template */
128 j = 0;
129 for (i = *mappdslen; i < newlen; i++)
130 {
131 nbits = abs(mappds->ext[j]) * 8;
132 if (mappds->ext[j] >= 0)
133 {
134 gbit(cgrib, lipdstmpl + i, *iofst, nbits);
135 }
136 else
137 {
138 gbit(cgrib, &isign, *iofst, 1);
139 gbit(cgrib, lipdstmpl + i, *iofst+1, nbits-1);
140 if (isign == 1)
141 lipdstmpl[i] = -1 * lipdstmpl[i];
142 }
143 *iofst = *iofst + nbits;
144 j++;
145 }
146 *mappdslen = newlen;
147 }
148 if (mappds->ext)
149 free(mappds->ext);
150 if (mappds)
151 free(mappds);
152
153 /* Get Optional list of vertical coordinate values after the
154 * Product Definition Template, if necessary. */
155 *coordlist = NULL;
156 if (*numcoord != 0)
157 {
158 coordieee = calloc(*numcoord, sizeof(g2int));
159 lcoordlist = calloc(*numcoord, sizeof(float));
160 if (coordieee == 0 || lcoordlist == 0)
161 {
162 *numcoord = 0;
163 *coordlist = NULL;
164 if (coordieee)
165 free(coordieee);
166 if (lcoordlist)
167 free(lcoordlist);
168 return G2_UNPACK_NO_MEM;
169 }
170 else
171 {
172 *coordlist = lcoordlist;
173 }
174 gbits(cgrib, coordieee, *iofst, 32, 0, *numcoord);
175 rdieee(coordieee, *coordlist, *numcoord);
176 free(coordieee);
177 *iofst = *iofst + (32 * (*numcoord));
178 }
179
180 return G2_NO_ERROR;
181}
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:464
#define G2_UNPACK4_BAD_PDT
In g2_unpack4(), undefined Product Definition Template.
Definition grib2.h:467
#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
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: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
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:286
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:276