/src/gdal/frmts/grib/degrib/g2clib/g2_unpack3.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <stdio.h> |
2 | | #include <stdlib.h> |
3 | | #include "grib2.h" |
4 | | |
5 | | |
6 | | 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 | 31.5k | { |
70 | 31.5k | g2int ierr,i,j,nbits,isecnum = 0; |
71 | 31.5k | g2int lensec = 0,ibyttem=0,isign = 0,newlen; |
72 | 31.5k | g2int *ligds,*ligdstmpl=0,*lideflist=0; |
73 | 31.5k | gtemplate *mapgrid; |
74 | | |
75 | 31.5k | ierr=0; |
76 | 31.5k | *igds=0; // NULL |
77 | 31.5k | *igdstmpl=0; // NULL |
78 | 31.5k | *ideflist=0; // NULL |
79 | | |
80 | 31.5k | gbit2(cgrib,cgrib_length,&lensec,*iofst,32); // Get Length of Section |
81 | 31.5k | *iofst=*iofst+32; |
82 | 31.5k | gbit2(cgrib,cgrib_length,&isecnum,*iofst,8); // Get Section Number |
83 | 31.5k | *iofst=*iofst+8; |
84 | | |
85 | 31.5k | 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 | 0 | } |
92 | | |
93 | 31.5k | ligds=(g2int *)calloc(5,sizeof(g2int)); |
94 | 31.5k | *igds=ligds; |
95 | | |
96 | 31.5k | gbit2(cgrib,cgrib_length,ligds+0,*iofst,8); // Get source of Grid def. |
97 | 31.5k | *iofst=*iofst+8; |
98 | 31.5k | gbit2(cgrib,cgrib_length,ligds+1,*iofst,32); // Get number of grid pts. |
99 | 31.5k | *iofst=*iofst+32; |
100 | 31.5k | gbit2(cgrib,cgrib_length,ligds+2,*iofst,8); // Get num octets for opt. list |
101 | 31.5k | *iofst=*iofst+8; |
102 | 31.5k | gbit2(cgrib,cgrib_length,ligds+3,*iofst,8); // Get interpret. for opt. list |
103 | 31.5k | *iofst=*iofst+8; |
104 | 31.5k | gbit2(cgrib,cgrib_length,ligds+4,*iofst,16); // Get Grid Def Template num. |
105 | 31.5k | *iofst=*iofst+16; |
106 | | |
107 | 31.5k | if (ligds[4] != 65535) { |
108 | | // Get Grid Definition Template |
109 | 31.5k | mapgrid=getgridtemplate(ligds[4]); |
110 | 31.5k | if (mapgrid == 0) { // undefined template |
111 | 15 | ierr=5; |
112 | 15 | return(ierr); |
113 | 15 | } |
114 | 31.5k | *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 | 31.5k | if (*mapgridlen > 0) { |
121 | 31.5k | ligdstmpl=0; |
122 | 31.5k | ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int)); |
123 | 31.5k | 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 | 0 | } |
130 | 31.5k | else { |
131 | 31.5k | *igdstmpl=ligdstmpl; |
132 | 31.5k | } |
133 | 31.5k | } |
134 | 31.5k | ibyttem=0; |
135 | 733k | for (i=0;i<*mapgridlen;i++) { |
136 | 701k | nbits=abs(mapgrid->map[i])*8; |
137 | 701k | if ( mapgrid->map[i] >= 0 ) { |
138 | 526k | gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits); |
139 | 526k | } |
140 | 175k | else { |
141 | 175k | gbit2(cgrib,cgrib_length,&isign,*iofst,1); |
142 | 175k | gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1); |
143 | 175k | if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i]; |
144 | 175k | } |
145 | 701k | *iofst=*iofst+nbits; |
146 | 701k | ibyttem=ibyttem+abs(mapgrid->map[i]); |
147 | 701k | } |
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 | 31.5k | 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 | 0 | { |
168 | 0 | ierr = 6; |
169 | 0 | break; |
170 | 0 | } |
171 | 0 | } |
172 | 0 | 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 | 0 | { |
176 | 0 | ierr = 6; |
177 | 0 | break; |
178 | 0 | } |
179 | 0 | if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i]; |
180 | 0 | } |
181 | 0 | *iofst=*iofst+nbits; |
182 | 0 | ibyttem=ibyttem+abs(mapgrid->ext[j]); |
183 | 0 | j++; |
184 | 0 | } |
185 | 0 | *mapgridlen=newlen; |
186 | 0 | } |
187 | 31.5k | free(mapgrid->ext); |
188 | 31.5k | free(mapgrid); |
189 | 31.5k | if( ierr != 0 ) |
190 | 0 | { |
191 | 0 | *idefnum=0; |
192 | 0 | *ideflist=0; //NULL |
193 | 0 | return(ierr); |
194 | 0 | } |
195 | 31.5k | } |
196 | 3 | else { // No Grid Definition Template |
197 | 3 | *mapgridlen=0; |
198 | 3 | *igdstmpl=0; |
199 | 3 | } |
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 | 31.5k | if ( ligds[2] != 0 ) { |
206 | 2 | nbits=ligds[2]*8; |
207 | 2 | *idefnum=(lensec-14-ibyttem)/ligds[2]; |
208 | 2 | if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int)); |
209 | 2 | if (lideflist == 0) { |
210 | 2 | ierr=6; |
211 | 2 | *idefnum=0; |
212 | 2 | *ideflist=0; //NULL |
213 | 2 | return(ierr); |
214 | 2 | } |
215 | 0 | else { |
216 | 0 | *ideflist=lideflist; |
217 | 0 | } |
218 | 0 | gbits(cgrib,cgrib_length,lideflist,*iofst,nbits,0,*idefnum); |
219 | 0 | *iofst=*iofst+(nbits*(*idefnum)); |
220 | 0 | } |
221 | 31.5k | else { |
222 | 31.5k | *idefnum=0; |
223 | 31.5k | *ideflist=0; // NULL |
224 | 31.5k | } |
225 | | |
226 | 31.5k | return(ierr); // End of Section 3 processing |
227 | 31.5k | } |