1 : #include <stdio.h>
2 : #include <stdlib.h>
3 : #include "grib2.h"
4 :
5 :
6 2 : g2int g2_unpack3(unsigned char *cgrib,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 ontaining 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 : // Defintion Template 3.NN
46 : // mapgridlen- Number of elements in igdstmpl[]. i.e. number of entries
47 : // in Grid Defintion 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 : g2int ierr,i,j,nbits,isecnum;
71 2 : g2int lensec,ibyttem=0,isign,newlen;
72 2 : g2int *ligds,*ligdstmpl=0,*lideflist=0;
73 : xxtemplate *mapgrid;
74 :
75 2 : ierr=0;
76 2 : *igds=0; // NULL
77 2 : *igdstmpl=0; // NULL
78 2 : *ideflist=0; // NULL
79 :
80 2 : gbit(cgrib,&lensec,*iofst,32); // Get Length of Section
81 2 : *iofst=*iofst+32;
82 2 : gbit(cgrib,&isecnum,*iofst,8); // Get Section Number
83 2 : *iofst=*iofst+8;
84 :
85 2 : 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 2 : ligds=(g2int *)calloc(5,sizeof(g2int));
94 2 : *igds=ligds;
95 :
96 2 : gbit(cgrib,ligds+0,*iofst,8); // Get source of Grid def.
97 2 : *iofst=*iofst+8;
98 2 : gbit(cgrib,ligds+1,*iofst,32); // Get number of grid pts.
99 2 : *iofst=*iofst+32;
100 2 : gbit(cgrib,ligds+2,*iofst,8); // Get num octets for opt. list
101 2 : *iofst=*iofst+8;
102 2 : gbit(cgrib,ligds+3,*iofst,8); // Get interpret. for opt. list
103 2 : *iofst=*iofst+8;
104 2 : gbit(cgrib,ligds+4,*iofst,16); // Get Grid Def Template num.
105 2 : *iofst=*iofst+16;
106 :
107 2 : if (ligds[4] != 65535) {
108 : // Get Grid Definition Template
109 2 : mapgrid=getgridtemplate(ligds[4]);
110 2 : if (mapgrid == 0) { // undefined template
111 0 : ierr=5;
112 0 : return(ierr);
113 : }
114 2 : *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 2 : if (*mapgridlen > 0) {
121 2 : ligdstmpl=0;
122 2 : ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int));
123 2 : if (ligdstmpl == 0) {
124 0 : ierr=6;
125 0 : *mapgridlen=0;
126 0 : *igdstmpl=0; //NULL
127 0 : if( mapgrid != 0 ) free(mapgrid);
128 0 : return(ierr);
129 : }
130 : else {
131 2 : *igdstmpl=ligdstmpl;
132 : }
133 : }
134 2 : ibyttem=0;
135 40 : for (i=0;i<*mapgridlen;i++) {
136 38 : nbits=abs(mapgrid->map[i])*8;
137 38 : if ( mapgrid->map[i] >= 0 ) {
138 28 : gbit(cgrib,ligdstmpl+i,*iofst,nbits);
139 : }
140 : else {
141 10 : gbit(cgrib,&isign,*iofst,1);
142 10 : gbit(cgrib,ligdstmpl+i,*iofst+1,nbits-1);
143 10 : if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
144 : }
145 38 : *iofst=*iofst+nbits;
146 38 : 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 2 : 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 : gbit(cgrib,ligdstmpl+i,*iofst,nbits);
167 : }
168 : else {
169 0 : gbit(cgrib,&isign,*iofst,1);
170 0 : gbit(cgrib,ligdstmpl+i,*iofst+1,nbits-1);
171 0 : if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
172 : }
173 0 : *iofst=*iofst+nbits;
174 0 : ibyttem=ibyttem+abs(mapgrid->ext[j]);
175 0 : j++;
176 : }
177 0 : *mapgridlen=newlen;
178 : }
179 2 : if( mapgrid->ext != 0 ) free(mapgrid->ext);
180 2 : if( mapgrid != 0 ) free(mapgrid);
181 : }
182 : else { // No Grid Definition Template
183 0 : *mapgridlen=0;
184 0 : *igdstmpl=0;
185 : }
186 : //
187 : // Unpack optional list of numbers defining number of points
188 : // in each row or column, if included. This is used for non regular
189 : // grids.
190 : //
191 2 : if ( ligds[2] != 0 ) {
192 0 : nbits=ligds[2]*8;
193 0 : *idefnum=(lensec-14-ibyttem)/ligds[2];
194 0 : if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int));
195 0 : if (lideflist == 0) {
196 0 : ierr=6;
197 0 : *idefnum=0;
198 0 : *ideflist=0; //NULL
199 0 : return(ierr);
200 : }
201 : else {
202 0 : *ideflist=lideflist;
203 : }
204 0 : gbits(cgrib,lideflist,*iofst,nbits,0,*idefnum);
205 0 : *iofst=*iofst+(nbits*(*idefnum));
206 : }
207 : else {
208 2 : *idefnum=0;
209 2 : *ideflist=0; // NULL
210 : }
211 :
212 2 : return(ierr); // End of Section 3 processing
213 : }
|