Line data Source code
1 : #include <stdio.h>
2 : #include <stdlib.h>
3 : #include "grib2.h"
4 :
5 :
6 472 : g2int g2_unpack3(unsigned char *cgrib,g2int cgrib_length,g2int *iofst,g2int **igds,g2int **igdstmpl,
7 : g2int *mapgridlen,g2int **ideflist,g2int *idefnum)
8 : ////$$$ SUBPROGRAM DOCUMENTATION BLOCK
9 : // . . . .
10 : // SUBPROGRAM: g2_unpack3
11 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31
12 : //
13 : // ABSTRACT: This routine unpacks Section 3 (Grid Definition Section)
14 : // as defined in GRIB Edition 2.
15 : //
16 : // PROGRAM HISTORY LOG:
17 : // 2002-10-31 Gilbert
18 : //
19 : // USAGE: int g2_unpack3(unsigned char *cgrib,g2int *iofst,g2int **igds,
20 : // g2int **igdstmpl,g2int *mapgridlen,
21 : // g2int **ideflist,g2int *idefnum)
22 : // INPUT ARGUMENTS:
23 : // cgrib - Char array containing Section 3 of the GRIB2 message.
24 : // iofst - Bit offset for the beginning of Section 3 in cgrib.
25 : //
26 : // OUTPUT ARGUMENTS:
27 : // iofst - Bit offset at the end of Section 3, returned.
28 : // igds - Contains information read from the appropriate GRIB Grid
29 : // Definition Section 3 for the field being returned.
30 : // igds[0]=Source of grid definition (see Code Table 3.0)
31 : // igds[1]=Number of grid points in the defined grid.
32 : // igds[2]=Number of octets needed for each
33 : // additional grid points definition.
34 : // Used to define number of
35 : // points in each row ( or column ) for
36 : // non-regular grids.
37 : // = 0, if using regular grid.
38 : // igds[3]=Interpretation of list for optional points
39 : // definition. (Code Table 3.11)
40 : // igds[4]=Grid Definition Template Number (Code Table 3.1)
41 : // igdstmpl - Pointer to integer array containing the data values for
42 : // the specified Grid Definition
43 : // Template ( NN=igds[4] ). Each element of this integer
44 : // array contains an entry (in the order specified) of Grid
45 : // Definition Template 3.NN
46 : // mapgridlen- Number of elements in igdstmpl[]. i.e. number of entries
47 : // in Grid Definition Template 3.NN ( NN=igds[4] ).
48 : // ideflist - (Used if igds[2] .ne. 0) Pointer to integer array containing
49 : // the number of grid points contained in each row ( or column ).
50 : // (part of Section 3)
51 : // idefnum - (Used if igds[2] .ne. 0) The number of entries
52 : // in array ideflist. i.e. number of rows ( or columns )
53 : // for which optional grid points are defined.
54 : // ierr - Error return code.
55 : // 0 = no error
56 : // 2 = Not Section 3
57 : // 5 = "GRIB" message contains an undefined Grid Definition
58 : // Template.
59 : // 6 = memory allocation error
60 : //
61 : // REMARKS:
62 : //
63 : // ATTRIBUTES:
64 : // LANGUAGE: C
65 : // MACHINE:
66 : //
67 : //$$$
68 :
69 : {
70 472 : g2int ierr,i,j,nbits,isecnum = 0;
71 472 : g2int lensec = 0,ibyttem=0,isign = 0,newlen;
72 472 : g2int *ligds,*ligdstmpl=0,*lideflist=0;
73 : gtemplate *mapgrid;
74 :
75 472 : ierr=0;
76 472 : *igds=0; // NULL
77 472 : *igdstmpl=0; // NULL
78 472 : *ideflist=0; // NULL
79 :
80 472 : gbit2(cgrib,cgrib_length,&lensec,*iofst,32); // Get Length of Section
81 472 : *iofst=*iofst+32;
82 472 : gbit2(cgrib,cgrib_length,&isecnum,*iofst,8); // Get Section Number
83 472 : *iofst=*iofst+8;
84 :
85 472 : if ( isecnum != 3 ) {
86 0 : ierr=2;
87 0 : *idefnum=0;
88 0 : *mapgridlen=0;
89 : // fprintf(stderr,"g2_unpack3: Not Section 3 data.\n");
90 0 : return(ierr);
91 : }
92 :
93 472 : ligds=(g2int *)calloc(5,sizeof(g2int));
94 472 : *igds=ligds;
95 :
96 472 : gbit2(cgrib,cgrib_length,ligds+0,*iofst,8); // Get source of Grid def.
97 472 : *iofst=*iofst+8;
98 472 : gbit2(cgrib,cgrib_length,ligds+1,*iofst,32); // Get number of grid pts.
99 472 : *iofst=*iofst+32;
100 472 : gbit2(cgrib,cgrib_length,ligds+2,*iofst,8); // Get num octets for opt. list
101 472 : *iofst=*iofst+8;
102 472 : gbit2(cgrib,cgrib_length,ligds+3,*iofst,8); // Get interpret. for opt. list
103 472 : *iofst=*iofst+8;
104 472 : gbit2(cgrib,cgrib_length,ligds+4,*iofst,16); // Get Grid Def Template num.
105 472 : *iofst=*iofst+16;
106 :
107 472 : if (ligds[4] != 65535) {
108 : // Get Grid Definition Template
109 472 : mapgrid=getgridtemplate(ligds[4]);
110 472 : if (mapgrid == 0) { // undefined template
111 0 : ierr=5;
112 0 : return(ierr);
113 : }
114 472 : *mapgridlen=mapgrid->maplen;
115 : //
116 : // Unpack each value into array igdstmpl from the
117 : // the appropriate number of octets, which are specified in
118 : // corresponding entries in array mapgrid.
119 : //
120 472 : if (*mapgridlen > 0) {
121 472 : ligdstmpl=0;
122 472 : ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int));
123 472 : if (ligdstmpl == 0) {
124 0 : ierr=6;
125 0 : *mapgridlen=0;
126 0 : *igdstmpl=0; //NULL
127 0 : free(mapgrid);
128 0 : return(ierr);
129 : }
130 : else {
131 472 : *igdstmpl=ligdstmpl;
132 : }
133 : }
134 472 : ibyttem=0;
135 10057 : for (i=0;i<*mapgridlen;i++) {
136 9585 : nbits=abs(mapgrid->map[i])*8;
137 9585 : if ( mapgrid->map[i] >= 0 ) {
138 7231 : gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits);
139 : }
140 : else {
141 2354 : gbit2(cgrib,cgrib_length,&isign,*iofst,1);
142 2354 : gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1);
143 2354 : if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
144 : }
145 9585 : *iofst=*iofst+nbits;
146 9585 : ibyttem=ibyttem+abs(mapgrid->map[i]);
147 : }
148 : //
149 : // Check to see if the Grid Definition Template needs to be
150 : // extended.
151 : // The number of values in a specific template may vary
152 : // depending on data specified in the "static" part of the
153 : // template.
154 : //
155 472 : if ( mapgrid->needext == 1 ) {
156 0 : free(mapgrid);
157 0 : mapgrid=extgridtemplate(ligds[4],ligdstmpl);
158 : // Unpack the rest of the Grid Definition Template
159 0 : newlen=mapgrid->maplen+mapgrid->extlen;
160 0 : ligdstmpl=(g2int *)realloc(ligdstmpl,newlen*sizeof(g2int));
161 0 : *igdstmpl=ligdstmpl;
162 0 : j=0;
163 0 : for (i=*mapgridlen;i<newlen;i++) {
164 0 : nbits=abs(mapgrid->ext[j])*8;
165 0 : if ( mapgrid->ext[j] >= 0 ) {
166 0 : if(gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits) < 0)
167 : {
168 0 : ierr = 6;
169 0 : break;
170 : }
171 : }
172 : else {
173 0 : if( gbit2(cgrib,cgrib_length,&isign,*iofst,1) < 0 ||
174 0 : gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1) < 0 )
175 : {
176 0 : ierr = 6;
177 0 : break;
178 : }
179 0 : if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
180 : }
181 0 : *iofst=*iofst+nbits;
182 0 : ibyttem=ibyttem+abs(mapgrid->ext[j]);
183 0 : j++;
184 : }
185 0 : *mapgridlen=newlen;
186 : }
187 472 : free(mapgrid->ext);
188 472 : free(mapgrid);
189 472 : if( ierr != 0 )
190 : {
191 0 : *idefnum=0;
192 0 : *ideflist=0; //NULL
193 0 : return(ierr);
194 : }
195 : }
196 : else { // No Grid Definition Template
197 0 : *mapgridlen=0;
198 0 : *igdstmpl=0;
199 : }
200 : //
201 : // Unpack optional list of numbers defining number of points
202 : // in each row or column, if included. This is used for non regular
203 : // grids.
204 : //
205 472 : if ( ligds[2] != 0 ) {
206 0 : nbits=ligds[2]*8;
207 0 : *idefnum=(lensec-14-ibyttem)/ligds[2];
208 0 : if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int));
209 0 : if (lideflist == 0) {
210 0 : ierr=6;
211 0 : *idefnum=0;
212 0 : *ideflist=0; //NULL
213 0 : return(ierr);
214 : }
215 : else {
216 0 : *ideflist=lideflist;
217 : }
218 0 : gbits(cgrib,cgrib_length,lideflist,*iofst,nbits,0,*idefnum);
219 0 : *iofst=*iofst+(nbits*(*idefnum));
220 : }
221 : else {
222 472 : *idefnum=0;
223 472 : *ideflist=0; // NULL
224 : }
225 :
226 472 : return(ierr); // End of Section 3 processing
227 : }
|